עבור לתוכן

הורשה public בC++

Featured Replies

פורסם

הי. אני רוצה במחלקה נורשת (drived), להגדיר את אחת הפונקציות של מחלקת האב כprotected (כשהיא במקור public, ובגלל סוג הורשה public היא נשארת כזו..)

תגידו בבקשה אם המימוש הסמלי הזה נכון. מחלקת אב

class A
{
public:
String func(){return "Hello";}
}
הגדרה של מחלקה
נורשת
class B : public A
}
protected:
String func() {return A::func();}
{

מותר לעשות מה שעשיתי? (בבקשה אל תגידו "פשוט היית עושה מהתחלה הורשה מסוג protected" כי זאת רק דוגמא)

פורסם

ערוך את ההודעה ושים את הקוד בתוך טג קוד, כדי שיהיה קריא יותר.

קלאס בן לא יכול לשנות שום דבר בקלאס האב. הדבר היחיד שהוא יכול לעשות זה להוסיף דברים ולדרוס מתודות וירטואליות (ייתכן שמותר לו להעלות את הנראות של המתודה, אבל בטוח לא להוריד אותה). אני לא סגור על האם מותר לו להגדיר מתודה חדשה בשם של מתודה (לא וירטואלית) שקיימת בקלאס האב - הכי מומלץ לבדוק את זה בעצמך.

פורסם

ערוך את ההודעה ושים את הקוד בתוך טג קוד, כדי שיהיה קריא יותר.

קלאס בן לא יכול לשנות שום דבר בקלאס האב. הדבר היחיד שהוא יכול לעשות זה להוסיף דברים ולדרוס מתודות וירטואליות (ייתכן שמותר לו להעלות את הנראות של המתודה, אבל בטוח לא להוריד אותה). אני לא סגור על האם מותר לו להגדיר מתודה חדשה בשם של מתודה (לא וירטואלית) שקיימת בקלאס האב - הכי מומלץ לבדוק את זה בעצמך.

מותר. קוראים לזה method hiding. זה לא מומלץ.

לא כדאי להפוך פונקציות פומביות באבא לפרטיות בבן.

פורסם
  • מחבר

הי

הכנסתי לקוד טאג, הסוגריים למטה יצאו הפוכים אז תתעלמו. מקווה שזה יותר קריא.

אכן, אני מבין שזה לא מומלץ.. אבל אני כרגע פותר תרגיל, ומחלקה A (מחלקת ה"אב") נתונה -אסור לגעת בה, ובpublic שלה יש חשיפה למימוש. במחלקה שאני בונה, הנורשת מA, רשום בהוראות לוודא איסור חשיפה למימוש. כלומר במחלקה הנורשת B, אני צריך לדאוג שכמה פונקציות פולשניות מA לא יהיו עם גישה לכל משתמש שיוצר משתנה מחלקה B.

תוך כדי שאני מדבר איתכם, עלה לי רעיון שאולי לדעתכם עדיף: במקום להפוך לprotected, להפוך לstatic. כלומר

static String func() {return A::func();}

זה יהיה פחות נורא? עדיין משיגים אי חשיפה

פורסם
  • מחבר

Zelig קראתי את הלינק שלך, סתכל כאן

Should a derived class redefine ("override") a member function that is

non-[tt]virtual[/tt] in a base class?

It's legal, but it ain't moral.

Experienced C++ programmers will sometimes redefine a non-[tt]virtual[/tt]

function for efficiency (e.g., if the derived class implementation can make

better use of the derived class's resources) or to get around the hiding

rule. However the client-visible effects must

be identical,since non-[tt]virtual[/tt] functions are dispatched based

on the static type of the pointer/reference rather than the dynamic type of the

pointed-to/referenced object.

תראה, את הקטע עם הפוינטר הדינמי\סטטי ידעתי. זה לא רלוונטי במקרה שלי, כי אין עוד מחלקה נורשת מהמחלקה שאני בונה (ואי אפשר להציב משתנה מסוג מחלקה נורשת לתוך הורים שלה, מבחינת קומפילציה זה לא יעבור). אז אני לא רואה בעיה כזאת.

הם גם רשמו שאם כבר, המימוש צריך להיות זהה- המימוש שהצעתי אכן זהה לפונקציה המקורית אחד לאחד.. אני בסך הכל הופך אותו לprotected כדי למנוע מהיוזר חשיפה למימוש

פורסם

אבל אתה לא "הופך אותו ל-protected". אתה יוצר מתודה חדשה לחלוטין בשם func. אני אפילו לא בטוח שזה יסתיר את ה-func שהוגדר ב-A (כלומר, יכול להיות שקריאה ל-b.func מחוץ למחלקה B פשוט תקרא לפונקציה של A, שעברה בירושה). הפונקציה func של A עדיין תהיה נגישה גם למשתנים מטיפוס B, ע"י upcast פשוט (אי אפשר לעשות את זה עם משתנה מטיפוס B, אבל כן אפשר עם מצביע ל-B).

בכל מקרה זה מכוער ולא מומלץ. אם תסביר מה אתה צריך לעשות אולי נוכל לעזור לך לעשות את זה באופן נכון.

פורסם
  • מחבר

הסברתי מה אני צריך לעשות

אבל אני כרגע פותר תרגיל, ומחלקה A (מחלקת ה"אב") נתונה -אסור לגעת בה, ובpublic שלה יש חשיפה למימוש. במחלקה שאני בונה, הנורשת מA, רשום בהוראות לוודא איסור חשיפה למימוש. כלומר במחלקה הנורשת B, אני צריך לדאוג שכמה פונקציות פולשניות מA לא יהיו עם גישה לכל משתמש שיוצר משתנה מחלקה B.

תוך כדי שאני מדבר איתכם, עלה לי רעיון שאולי לדעתכם עדיף: במקום להפוך לprotected, להפוך לstatic. כלומר

static String func() {return A::func();}

יהיה פחות נורא? עדיין משיגים אי חשיפה

פורסם

גם static לא יסתיר בשום צורה.

אם אתה רוצה לרשת מ-A בלי לחשוף את זה, אתה צריך להשתמש בירושה פרטית (private inheritance), אבל אז אף אחת מהפונקציות של A לא יהיו נגישות ב-B.

מי שנתן לך את התרגיל הזה, אגב, צריך לקבל מכות.

פורסם
  • מחבר

ברור לי שזה מימוש לא אופטימלי.. אבל באחד התרגולים למדנו על method hiding (ועל הבעיתיות שלו, גם) אז אני מניח שרוצים שנשתמש בזה.

פונקציה סטטית זמינה רק במחלקה שלה (או החברות). מבחינתי היא "עושה את העבודה" בדיוק כמו protected. אתה יוצא מנקודת הנחה שmethod hiding פשוט לא אפשרי, תקרא בלינקים של Zelig - זה לא מומלץ אבל חוקי.. גם במוסד שאני לומד אני זוכר שלמדנו את זה לפני פונקציה וירטואלית.

פורסם

מתודה סטטית לא מסתירה כלום, ואין קשר בינה לבין ירושה. מתודה סטטית היא class member (כלומר היא איבר של המחלקה) ולא instance member (איבר של מופע של המחלקה). מה שזמין רק במחלקה או בחברים שלה זה private.

פורסם
  • מחבר

אוקי. שאלה אחרונה קטנה, לא רציתי לפתור שרשור רק בשביל זה. סתכל בבקשה בקוד



class A
{
protected:
int x = 8;
friend int func();
};
int func() { A var; return var.x }

אני מניח שהפונקציה func תעבוד, כי היא הוגדרה כfriend. זה משנה תחת איזה שדה (public,protected,private) היא הוגדרה כfriend? (אני למשל כרגע שמתי אותה בתוך השדה של protected.. כמו שאפשר לראות)

פורסם

הסברתי מה אני צריך לעשות

אתה בטוח שאמרו לך במפורש שאתה אמור לרשת\להרחיב את מחלקה A?

לפי התיאור של התרגיל שלך נראה לי שיותר הגיוני שמחלקה A מוכלת שמשתנה פרטי בתוך B וכך אין גישה חיצונית לA מ B

אך B כן יכול להשתמש בשיטות שנמצאות בA.

פורסם

אין בעיה לעשות את זה עם ירושה, פשוט צריך ירושה פרטית (כלומר בהגדרה של B כותבים class B : private A).

פורסם

נראה כאילו אין טעם לירושה פה פשוט....

כמובן שאפשר לרשת מכל דבר אבל מבחינת התכנון צריך שתהיה לירושה סיבה.

ולא נראה שיש סיבה לרשת כאן

ארכיון

דיון זה הועבר לארכיון ולא ניתן להוסיף בו תגובות חדשות.

דיונים חדשים