Hilfe zu polymorphie Aufgabe
-
Hiho,
Ich bin grad dabei alte Klausuren für kommende Informatik Klausur zu lösen. Doch bei einer Aufgabe kann ich mir das resultat im Compiler einfach nicht erklären.
class A { protected: string name; public: A(string name="NN") : name(name) {}; virtual string getName() const { return "A::getName: name = " + name; } virtual void print(bool nl=true) const { if (nl) cout << "A::print - "; cout << getName(); if (nl) cout << endl; } }; class B : virtual public A { string b; public: B(string name, string b="B") : A(name), b(b) {}; virtual void print(bool nl=true) const { if (nl) cout << "B::print - "; A::print(false); cout << ", b=" << b; if (nl) cout << endl; } }; class C : public B { string c; public: C(string name, string c="C", string b="B") : B(name,b), c(c) {}; string getName() const { return "C::getName: name = " + name; } virtual void print(bool nl=true) { if (nl) cout << "C::print - "; B::print(false); cout << ", c=" << c; if (nl) cout << endl; } }; int main() { C c("C-Obj"); C * cptr = &c; ((A*)(cptr))->print(); //ruft print() aus Klasse B auf return 0; }In der dritten Zeile der Main wird das Print() der Klasse B aufgerufen aber warum?
Ich dachte der Cast davor ist egal weil eh in der Virtuellen Tabelle geschaut wird und dann das Print von C aufgerufen wird. Aber dem scheint nicht so zu sein
Dazu kommt noch das die Print Methoden von A und B const sind im Gegensatz zur Print von C. Da const zur Signatur zählt kann es doch überhaupt nicht sein, dass das Print von B aufgerufen wird. Ich bin verwirrt
MFG Fy
-
Fy schrieb:
Dazu kommt noch das die Print Methoden von A und B const sind im Gegensatz zur Print von C. Da const zur Signatur zählt kann es doch überhaupt nicht sein, dass das Print von B aufgerufen wird. Ich bin verwirrt

Doch, genau das dürfte der Grund sein, warum die Methode von B aufgerufen wird. B::print() hat die selbe Signatur wie A::print() und wird deshalb virtuell aufgerufen, C::print() hat eine andere Signatur und gilt deshalb als eigenständige Funktion.
-
Das print von C ist ein anderes als das von A und B, wegen dem Fehlen von
const.
-
Warum wird dann nicht das Print von A aufgerufen? Der Up-Cast geht ja auf A.
Oder wird nur in die VTabelle geschaut und der Cast ignoriert? Aber wie kommt Die Tabelle dann auf B::print()?Dass das Objekt nicht const ist aber eine const Methode aufruft ist dann egal?
-
Fy schrieb:
Warum wird dann nicht das Print von A aufgerufen? Der Up-Cast geht ja auf A.
Oder wird nur in die VTabelle geschaut und der Cast ignoriert? Aber wie kommt Die Tabelle dann auf B::print()?Bei virtuellen Methoden wird die Version der Klasse aufgerufen, die sie als letztes in der Hierarchie überschrieben hat (anhand der vtable) - und das ist in deinem Fall B (der Cast sorgt nur dafür, daß die von C definierte Funktion nicht mehr zur Verfügung steht, die hat einen eigenen Eintrag in der vtable).
PS: Klar darfst du für ein nicht-konstantes Objekt eine konstante Methode aufrufen.
-
CStoll schrieb:
Fy schrieb:
Warum wird dann nicht das Print von A aufgerufen? Der Up-Cast geht ja auf A.
Oder wird nur in die VTabelle geschaut und der Cast ignoriert? Aber wie kommt Die Tabelle dann auf B::print()?Bei virtuellen Methoden wird die Version der Klasse aufgerufen, die sie als letztes in der Hierarchie überschrieben hat (anhand der vtable) - und das ist in deinem Fall B (der Cast sorgt nur dafür, daß die von C definierte Funktion nicht mehr zur Verfügung steht, die hat einen eigenen Eintrag in der vtable).
PS: Klar darfst du für ein nicht-konstantes Objekt eine konstante Methode aufrufen.
Ah jetzt hab ichs verstanden. Vielen Dank
