Zitat von
Dax:
Zitat von
tommie-lie:
Warum überhaupt override bei Konstruktoren? Die sind doch gar nicht virtuell, macht ja auch keinen Sinn, virtuelle Konstruktoren zu haben
Wieso sollte das keinen Sinn machen?
Virtuelle Methoden nutzen die
RTTI um den tatsächlichen Typ ausfindig zu machen und dessen Methode aufzurufen. Ein sehr gutes Beispiel ist der Destruktor einer Klasse, dessen virtualität essenziell ist. Du kannst eine Variable vom Typ TObject haben und dort beliebige andere Typen drin erzeugen (SomeObject := TBlubb.Create). Rufst du jetzt den Destruktor dieser Variable auf, wird tatsächlich nicht der Destruktor von TObject aufgerufen, sondern der der tatsächlichen Instanz (im Beispiel der von TBlubb). Wäre der Destruktor nicht virtuell, würde der Destruktor von TObject aufgerufen, oder man müsste vorher in den richtigen Typ casten (TBlubb(SomeObject).Free), damit auch der richtige Destruktor aufgerufen wird und alle Ressourcen freigegeben werden.
Bei einem Konstruktor ist so ein Verhalten eigentlich unnötig. Ein Konstruktoraufruf sieht in Pascal üblicherweise so aus:
SomeVar := TSomeType.Create(Params);
Der Datentyp wird also explizit angegeben, es besteht nicht die geringste Frage, welcher Konstruktor aufgerufen werden soll, es muss der von TSomeType sein. Ein Aufruf, bei dem die Laufzeitinformation nötig wäre, wäre SomeVar.Create(Params), der aber keinen Sinn ergibt, da SomeVar entweder noch nicht instanziert war (dann kann es je nach Implementierung des Konstruktor gewaltig knallen, wie wir alle wissen), oder schon ein Objekt besaß, daß aber auch nach dem Aufruf noch in SomeVar bleibt. Es würde alleine der Konstruktor nochmal abgearbeitet werden (mit möglichen Initialisierngsfunktionen. Da ich kein Delphi zur Hand habe, kann ich nicht sagen, ob die üblichen Eigenschaften des Konstruktors auch bei bereits instanzierten Objekten gelten. Falls ja, wird unmittelbar vor dem Aufruf Speicher für eine neue Instanz des Objektes erzeugt und dieser als Rückgabewert zurückgegeben (das ist, was passiert, wenn man SomeVar := TSomeType.Create(Params); aufruft), der aber nirgends wieder referenziert wird. Wieder mangels vorhandenem Delphi bin ich mir nicht sicher, auf welches Objekt self zeigt, wenn man SomeVar.Create aufruft. Zeigt es auf SomeVar (und nicht auf das neu instanzierte Objekt), wäre der u.U. zurückgegebene, nicht referenzierte Speicher auch noch uninitialisiert, selbst wenn ich das Ergebnis also abfangen würde, wäre mein Objekt in einem unerwüsnchten Zustand.
Mir fällt keine Gelegenheit ein, bei der ein virtueller Konstruktor einen praktischen Sinn haben würde, denn von bereits instanzierten Objekten rufe ich keine Konstruktoren auf. Robert meinte, daß ab TComponent der Konstruktor virtual ist, die einzige Erklärung, die ich dafür finde, ist, daß die
IDE mit den Komponenten irgendwelche perversen Dinge anstellt, von denen ich lieber nicht wissen möchte, was es ist.