בסיסים וירטואלים

cyberia2ooo

New member
בסיסים וירטואלים

מסתבר שזהו קונספט שלא הבנתי משהו בו (או את הצורה בה ממשים אותו או את הקונספט עצמו) מישהו מוכן להסביר לי מה לא בסדר בקוד הבא:
#include <iostream> class VirtBase { public: virtual void funa() { std::cout<<"VirtBase::funa()"<<std::endl; } }; class DirA : public virtual VirtBase { public: void funa() { VirtBase::funa(); std::cout<<"DirA::funa()"<<std::endl; } }; class DirB : public virtual VirtBase { public: void funa() { VirtBase::funa(); std::cout<<"DirB::funa()"<<std::endl; } }; class DirC : public DirB, public DirA { public: void funa() { VirtBase::funa(); DirA::funa(); DirB::funa(); std::cout<<"Dirc::funa()"<<std::endl; } }; int main() { DirC C; C.funa(); return 0; }​
 

cyberia2ooo

New member
אמממ

זה פחות או יותר קוד שנלקח מהספר של סטראוסטרופ... בספר הוא אומר שהפונקציה VirtBase::funa תקרא רק פעם אחת, למרות ש DirC() קוראת לה באופן מפורש פעם אחד, ובאופן מרומז פעמיים (ע"י קח שהיא קוראת לפונקציות שקוראות לה)
 

Zack DA

New member
על כן נאמר, המנע מהורשה מרובה ../images/Emo6.gif

בכל אופן, בכלל לא בטוח שקומפיילרים נאמנים ל- Ansi.
 

cyberia2ooo

New member
אני בדרך כלל נמנע

אבל עדיין מעניין אותי למה כרגע זה לא פועל. אני משתמש ב g++ עם דגל ansi שעד עכשיו האמנתי שהוא נאמן לאנסי
 

Zack DA

New member
תראה, הקוד הועתק מסטרוסטרופ ועדיין

הוא לא פועל. גם דגל של אנסי לא באמת אומר שזה אנסי טהור. חוץ מזה, ירושה מרובה היא אחת מהנקודות הכי חלשות של קומפיילרים בכל הנוגע לתאימות לאנסי. איך אומר ידיד שלי,
"Ask a stupid ASCII, get a stupid Ansi"​
 

cyberia2ooo

New member
מובן לי

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

Zack DA

New member
אני מבין. אולי כמו שאמר אלדד,

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

cyberia2ooo

New member
אמממ

דבר ראשון... הקוד כן עובר קומפילציה וכן רץ. אבל, הפלט הוא לא כמו שהבנתי שהוא יהיה הפלט הוא
VirtBase::funa() VirtBase::funa() DirA::funa() VirtBase::funa() DirB::funa() DirC::funa()​
וזה לא שאני לא מבין מה קורה... הנק' היא, שלפי דברי ביארן, הפונקציה VirtBase::funa אמורה להקרות רק פעם אחת (זה מה שאני חושב שלא הבנתי... אולי היא נקראת רק פעם אחת רק במקרים מסויימים) אני יודע שאם אני אשתמש בקריאות מפורשות, אני אקבל בדיוק מה אני רוצה...
 

cyberia2ooo

New member
אוקיי לא משנה

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

eyalbd

New member
הקוד שלך בסדר

ואם יש לך שלוש קריאות כי זה מה שכתבת. קריאה explicit לפונקציה בבסיס הוירטואלי היא הכרחית באיתחול בלבד. דהיינו לקונסטרקטורים וגם כאן רק אם יש CTOR שהוא לא default. באופן כללי אם אתה משתמש במבנה "יהלום", תכנן שלבסיס הוירטואלי לא יהיה CTOR. זה לא קשור לANSI או לא. פשוט לא הבנת שמדובר באיתחול בלבד.
 

cyberia2ooo

New member
זה מה שכתבתי :)

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