עצור, עצור והזדהה

עצור, עצור והזדהה

שאלה ב c++ אם יש לי מצביע class ש 2 classes יורשים ממנו, איך ניתן בזמן ריצה לדעת מאיזה סוג של בן ה class שלי ? דוגמא: class a class b : public a class c : public a a* myA = new b() יש לי אפשרות לדעת ש a הוא מסוג b ולא c ?
 
אופרטור IS

ב C# יש אופרטור IS שמאפשר לשאול instace אם הוא מסוג class מסויים זאת המטרה של typeid או שיש דרך אחרת שיותר קרובה לאופרטור IS ?
 

frangelico

New member
דוגמא

class A {}; class B : public A {}; B b; A* pa = new B; if (typeid(b)) == typeid(B)) // if b is B - TRUE if(typeid(*pa) == typeid(B)) // if *pa is B - TRUE​
 
רק ../images/Emo91.gif קטנה...../images/Emo26.gif

בהרבה מאוד מקרים, כשאתה מוצא את עצמך בודק מה ה-type האמיתי של האובייקט שאתה מחזיק - סימן שמשהו ב-design ההתחלתי שלך דפוק! לא תמיד... זה לא גורף... אבל בהרבה מקרים - זה סימן לא טוב...
 

DNile

New member
רק אזהרה קטנה:

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

neko

New member
טריק נחמד - להגדיר פונק' ברמת

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

neko

New member
אבל אז האב חייב להיות VIRTUAL

(אני מניח שזה כמו ABSTRACT בJAVA, תקן אותי אם אני טועה) בעצמו...
 

vinney

Well-known member
רק הוא

אתה ממילא צריך לשנות אותו אם אתה מוסיף לשם פונקציות ממומשות על ריק, לא?
 

neko

New member
אבל יכול להיות שאתה מייצר

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

vinney

Well-known member
סליחה?

למה שאני אצטרך לממש רוטינה שהגדרתי כvirtual בכל בן??? למה מי מת? אתה מתבלבל בין virtual ל pure virtual (שזה הabstract בשפות אחרות).
 

DadleFish

New member
אתה מפספס משהו, neko

בשפת ++C פונקציה יכולה להיות virtual, או pure virtual. כשפונקציה היא virtual, זה אומר שבבנים שלה יהיה מימוש default של האבא, או מימוש מיוחד של הבן. לדוגמה:
class CBase { public: virtual void myFunc() { cout << "Hello, CBase!" << endl; } }; class CChild1 : public CBase { public: virtual void myFunc() { cout << "Hello, CChild1!" << endl; } }; class CChild2 : public CBase { }; int main() { CChild1 ch1; CChild2 ch2; ch1.myFunc(); // Will output "Hello, CChild1!" ch2.myFunc(); // Will output "Hello, CBase" return (0); }​
בפונקציה שהיא pure virtual, לעומת זאת, האבא לא מגדיר מימוש default לפונקציה אלא מגדיר אותה בכוונה בתור פונקציה לא ממומשת, כדי לכפות על היורשים שלו ליישם אותה. זו שיטה טובה להכתיב מימוש ליורשים. ככה מגדיר Pure virtual:
class CBase { public: virtual void mustBeImplementedInDerived() = 0; }; class CChild1 : public CBase { public: virtual void mustBeImplementedInDerived() { cout << "This is my implementation" << endl; } }; class CChild2 : public CBase { }; int main() { CChild1 ch1; // OK! CChild2 ch2; // NOT OK - CChild2 is abstract return (0); }​
הקוד הזה לא יתקמפל כי אי אפשר ליצור instance של CChild2, כי הוא אבסטרקטי (כיוון שלא מימש את הפונקציה הוירטואלית הטהורה).
 

neko

New member
../images/Emo51.gif, טוב לדעת.

ד"א, בדיוק היום נתקלתי בנושא בספר של OBJECT ORIENTED של MEYER שהתייחס לטעויות שנעשו ב++C בקביעת STATIC BINDING, ומתוך ההסבר הבנתי שVIRTUAL זה לא בדיוק מה שחשבתי...
 

Moridin

New member
מה לגבי

virtual static inline int type() { return 1; // a different number for each class }​
כמובן שזה תכנון גרוע של הקוד, אבל זה אפשרי ולדעתי זה גם אמור לעבוד...
 
למעלה