הורשה public בC++ - תכנות - HWzone פורומים
עבור לתוכן
  • צור חשבון

הורשה public בC++


yogev_23

Recommended Posts

הי. אני רוצה במחלקה נורשת (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.

קישור לתוכן
שתף באתרים אחרים

ארכיון

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

×
  • צור חדש...