Methode ersetzen / überlagern
-
Moin,
ich glaube ich habe ein Brett vorm Kopf. Auf jeden Fall komme ich nicht weiter.
Ich habe eine Klasse A in der es viele Methoden gibt die irgendwo die Methode tueDies(...) aufrufen.
Ich brauche die Klasse A jetzt mit einer anderen Methode tueDies(...). Daher dachte ich es wäre das Einfachste A zu erben und tueDies() zu überschreiben:Beispiel:
class A { public: A(){ ... tueDies(); } void tueDies(){ cout << "A"; } } class B : public A { B(...):A(); void tueDies(){ cout << "B"; } }
Wenn ich jetzt ein Objekt B erstelle wird A ausgegeben (gewünscht ist B). Wie schaffe ich es, dass die geerbten Methoden die überschriebene Methode aufrufen ohne Klasse A zu ändern? Das Problem ist, dass Klasse A sehr komplex ist. Es gibt > 100 Aufrufe von tueDies() in verschiedenen Methoden und Konstruktoren, so dass eine Überschreibung dieser keinen Sinn macht.
Vielen Dank für eure Hilfe
-
Wenn Du einen A-Zeiger(o. Referenz) verwendest mußt Du die Methode
virtual
machen.
Oder Du verwendest ein echtes B-Objekt:
`B b;b.tuWas();
`
-
Ich dachte ich verwende ein echtes Objekt B:
B * beispiel = new B(...);
Die Methoden werden nur intern aufgerufen. Gestartet durch einen Methodenaufruf im Konstruktor von A.
-
osfriese schrieb:
Ich dachte ich verwende ein echtes Objekt B:
B * beispiel = new B(...);
Die Methoden werden nur intern aufgerufen. Gestartet durch einen Methodenaufruf im Konstruktor von A.
Wenn Du's aus einem A rufst:
B::tuwas();
Edit: Wobei ich glaube, daß das im Konstruktor von A nicht funktionieren kann, da das B dort noch nicht existiert...
-
Vielen Dank!
Die Methode in Klasse A virtual zu setzen funktioniert.
Gibt es noch eine Möglichkeit das gleiche zu erreichen ohne Klasse A anzufassen?
-
osfriese schrieb:
Die Methode in Klasse A virtual zu setzen funktioniert.
Das glaube ich dir nicht so ganz. Mit dem Funktionsaufruf im Konstruktor von A kannst du gar nicht die Funktionen von Klasse B (ohne unsichere Hacks)* aufrufen, da zu diesem Zeitpunkt die Klasse B noch gar nicht erstellt wurde. Genausowenig ist klar ob gerade überhaupt ein B Objekt erstellt wird oder was anderes das auch von A erbt. Außerhalb des Konstruktors kannst du in Klasse A aber schon Funktionen von B aufrufen wenn die Funktion in Klasse A als virtual gekennzeichnet ist. Ohne etwas in A zu verändern geht es nicht.
*Tatsächlich fällt mir eine halbwegs sichere Methode mit Templates ein, aber das erwähne ich hier erstmal nicht, da du dich erstmal um Grundlagen kümmern solltest.
-
Caligulaminus schrieb:
Edit: Wobei ich glaube, daß das im Konstruktor von A nicht funktionieren kann, da das B dort noch nicht existiert...
Richtig, funktioniert nicht.
Der Standard definiert das so.Wobei es der Standard auch genau so gut anders hätte definieren können. In C# wird z.B. immer die Methode des "most derived type" aufgerufen, also in diesem Fall immer B.
(Was in C# weniger problematisch ist, weil man sich zumindest darauf verlassen kann dass alle Member "zero-initialized" worden sind bevor der erste Konstruktor anfing zu laufen (k.A. wie "zero-initialized" in C# korrekt heisst, aber ich denke es ist klar was ich meine). Bzw. werden auch Field-Initializer ausgeführt bevor irgend ein Ctor anfängt zu laufen.).