4.3.3. Upcasting, DowncastingCasting (המרה): המרת coercion של אובייקט ממחלקה נגזרת לאובייקט ממחלקת הבסיס. Up-casting: המרת מצביעים במעלה היררכית ההורשה (למשל, המרת מצביע מסוג עובד למצביע מסוג בן אדם). Up-casting של this מתבצע באופן אוטומטי בכל פעם שאנחנו משתמשים במתודה שנורשה ממחלקה אחרת. Emploee E; Manager M; M.is_manager_of(E) // Type of this is Manager*, // No casting occurs M.raise_salary(10); // Type of this is Employee* // in raise_salary. // Up casting must occur Down-casting: המרת מצביעים במורד גרף ההורשה. המרה זו חייבת להתבצע על ידי הוראה מפורטת. המרה זו נעשית רק במקרים מיוחדים – זו אינה המרה שנרצה לרוב לבצע. Employee E, *pE; Manager M, *pM; pE = &M; // OK: implicit upcasting. M = *pE; // Error: implicit downcasting is not allowed // explicit down casting: M = *(Manager *)pE; // deprecated syntax M = *static_cast<Manager*>pE; // recommended syntax נשים לב למה שכתוב בקוד – מומלץ להשתמש בהמרה על ידי static_cast, ולא בתחביר השני, המיועד בעיקר כדי לתמוך בקוד C ישן. המרת down-casting עשויה להיות לא חוקית. ניתן לבצע המרת down-casting בטוחה על ידי dynamic_cast. לדוגמא: Manager &mRef = dynamic_cast<Manager &>eRef; במידה ואי יהיה אפשר לבצע את ההמרה, שפת C++ תזרוק חריגה מסוג bad_cast. נביט בדוגמא לתוכנית בדיקה האם אובייקט הוא מסוג מסוים: #include <iostream> #include <cstdlib> using namespace std; class A { public: virtual void f() {}; }; class B : public A { public: void f() {}; }; class C { public: void f() {}; }; int main() { A *a1 = new A; A *b1 = new B; C *c1 = new C; if (B* ref1 = dynamic_cast<B*>(b1)) cout << "b1 is B" << endl; else cout << "b1 isn't B" << endl; if (C* ref1 = dynamic_cast<C*>(b1)) cout << "b1 is C" << endl; else cout << "b1 isn't C" << endl; return 0; } פלט התוכנית: b1 is B b1 isn't C
|
תוכן העניינים:
קישורים רלוונטיים:שיתוף: |
Borland style vptr
לפי מה שאני מכיר:"חסרון בגישה זו: גם כאשר איננו משתמשים ב-dynamic binding – אנחנו משלמים במקום"
לא נכון , עבור מחלקה A שאין לה מתודות דינמיות לא יווצר כלל המצביע, ולמשל עבור מחלקה B שיורשת מA פשוט נוסיף בהתחלה את המצביע, ואחרי הבלוק של A את שאר האינפורמציה של B . וככה לא משלמים על מה שלא משתמשים ועקרונות C++ נשמרים.
מה שכן באמת הcasting קצת יותר מסובך....