![]() |
Wann ein "inherited" im Constructor ?
Hallo,
wann muß ich ein inherited im Constructor verwenden? Vielen Dank E. B. |
Re: Wann ein "inherited" im Constructor ?
Ganz klar: immer.
Wenn du es lääst, wird der Konstruktorcode der Parentklasse nicht ausgeführt: viele Felder, die man später hundertprozentig braucht, bleiben uninitialisiert. |
Re: Wann ein "inherited" im Constructor ?
immer dann wenn du den Constructor der Klasse ausführen willst.
Bei TObject macht es nicht viel Sinn da der Constructor leer ist. Bei TComponente ist es hingegen wieder vorraussetzung um ordentlich damit arbeiten zu können weil recht viel im Constructor initialisiert wird was auch von Nachfahren benötigt wird. Man kann eigentlich immer mit inherited den Constructor der Klasse aufrufen von der man erbt außer man will nicht dass das ausgeführt wird. |
Re: Wann ein "inherited" im Constructor ?
Frage an die bisherigen Antworter (juhu, ein neues Wort erfunden...): Warum nicht einfach sagen, immer wenn der Constructor virtuell ist in der Basisklasse und wir ihn überschrieben haben (bzw. neu implementieren und den alten verstecken)? Afair ist ohne einen virtuellen Constructor auch kein Zwang da, inherited auf zu rufen.
Dies ist meine Behauptung, und nun ihr... :zwinker: |
Re: Wann ein "inherited" im Constructor ?
auch ein virtueller Constructor muss nicht zwangsläufig nach dem Überschreiben aufgerufen werden wenn im Constructor nix drin steht und dieser nur dazu dient das abgeleitete Klassen bestimmte Parameter erwarten.
|
Re: Wann ein "inherited" im Constructor ?
Zitat:
|
Re: Wann ein "inherited" im Constructor ?
Thomas, schau dir mal den Constructor von TPen oder TBrush an...
Gruß Hawkeye |
Re: Wann ein "inherited" im Constructor ?
Ja, ok, somit hatte ich Recht mit meiner Annahme bzw. Frage. Das inherited muss aufgerufen werden, wenn der Constructor in der Basisklasse virtuell ist und er somit überschrieben wurde bzw. man will den verdeckte virtuellen Constructor explizit aufrufen. Wenn ein Aufruf nicht gewollt ist, dann natürlich nicht. (ich hoffe damit habe ich alle Möglichkeiten abgedeckt).
Danke! /EDIT: Ok, dann eine Frage dazu: TGraphic führt einen virtuellen Constructor ein, aber warum wird innerhalb dessen denn "Inherited Create" aufgerufen? |
Re: Wann ein "inherited" im Constructor ?
Eigentlich wollte ich diese Aussage widerlegen:
Zitat:
Delphi-Quellcode:
Zu deiner TGraphic-Frage:
type
TMyPen = class (TPen) public constructor Create; end; constructor TMyPen.Create; begin inherited; end; procedure TForm1.Button1Click(Sender: TObject); var Pen : TMyPen; begin Pen := TMyPen.Create; Pen.Color := clRed; // ohne INHERITED in TMyPen.Create knallt es hier... Pen.Free; end; Zitat:
|
Re: Wann ein "inherited" im Constructor ?
Hallo,
nur wegen dem Borland Kommentar im Zitat von Hawkeye: der Object Pascal Compiler kennt zwar abstrakte virtuelle Konstruktoren - aber zur Laufzeit knallt es auf jeden Fall beim Aufruf von inherited im Konstruktor einer abgeleiteten Klasse. Irgendwie unbrauchbar. Freundliche Grüße |
Re: Wann ein "inherited" im Constructor ?
Ok, ich hatte nämlich im Code nachgeschaut und da TPen und TBrush mit ihren nicht virtuellen Constructoren auch kein inherited aufruft, dachte ich, du meinst dies als Bestätigung meiner These. In der VCL von Delphi 5 ist der Kommentar im Constructor von TGraphic nicht vorhanden, daher kam auch die Frage.
Ok, nun habe ich Bezug auf die Feststellungen hier noch ein Frage: Diese Constructor-Definitionen die wir hier nun haben (nicht virtuell, etc) - was für eine Art von Handling ist dies nun? Werden die Constructoren automatisch versteckt (bei anderer Signatur) und der neue eingeführt bzw. bei gleicher Signatur überschrieben? Beispiel dazu wie ich es meine:
Delphi-Quellcode:
TTest3.Create bietet mir Code-Insight nur den Constructor von TTest3 an.
type
TTest1 = Class Public Constructor Create; End; TTest2 = Class(TTest1) Public Constructor Create(Param: Integer); End; TTest3 = Class(TTest2) Public Constructor Create(neuerparam: Double); End; /EDIT: richtig virtuell können sie ja nicht sein - somit: wie wird das gehandhabt? |
Re: Wann ein "inherited" im Constructor ?
Man sollte immer inherited aufrufen. Auch fuer von TObject direkt abgeleitete Klassen. Da gibt es kein Problem und man kann spaeter enoetigenfalls eine Klassenstufe dazwischenschieben und hat dann keine Probleme mit einem vergessenen inherited-aufruf. So machen wir es in der JVCL und es hat bis heute gut geklappt.
|
Re: Wann ein "inherited" im Constructor ?
Zitat:
|
Re: Wann ein "inherited" im Constructor ?
Virtuelle Konstruktoren sind virtuelle Methoden der Metaklasse. Die Konstruktor-Virtualität wird nur für Klassenreferenzen (Variablen vom Typ der Metaklasse: class of TMyClass) benötigt. Es ist daher für die direkte Instanzierung einer Klasse unerheblich, ob der Konstruktor nun virtuell ist oder nicht, da man ihn direkt aufruft und nicht über die VMT der Metaklasse geht.
Beim Aufruf eines Konstruktor übergibt der Compiler einen versteckten Parameter (im DL-Register), der angibt, ob der "begin"-Code des Konstruktors die NewInstance() Klassenmethode (Methode der Metaklasse) aufrufen soll, die ihrerseits Speicher reserviert. Ruft man nun mittels inherited den Vorfahrkonstruktor auf, enthält dieser versteckte Parameter einen anderen Wert, wodurch kein erneutes NewInstance durchgeführt wird. Das inherited führt also den Vorfahrkonstruktor als normale Methode aus. Und wann sollte man inherited aufrufen? Immer dann wenn man die Funktionalität der Vorfahrklasse benötigt. Dies trifft beim Konstruktor natürlich immer dann ein, wenn der Vorfahrkonstruktor eine Initialisierung des Objekts vornimmt und man nicht aus irgendwelchen Gründen dies unterbinden will. Da TObject.Create nicht wirklich viel macht, außer dem "begin"-Code, der aber auch im Konstruktor der abgeleiteten Klasse vorhanden ist, ist es nicht unbedingt notwendig TObject.Create mittels inherited aufzurufen, da dort nichts mehr passiert. Stellt man aber zu einem späteren Zeitpunkt fest, dass man vielleicht doch besser eine Klasse dazwischen schieben sollte, kann das fehlende [b9inherited[/b] einem sehr viel Kopfschmerzen bereiten. Das inherited ist übrigens nicht mit dem virtual verbunden. Ein inherited wird vom Compiler immer direkt in einen absoluten Methoden-Aufruf ohne Umweg über die VMT kompiliert. Es findet also keine Bindung zur Laufzeit statt, sondern bereits zur Link-Zeit. Wenn Borland/CodeGear immernoch die Handbücher zu TurboPascal 4.0, 5.0 und 5.5 verkaufen würde, wüssten einige Programmierer mehr über manche Interna bescheid. Aber leider wurden die Handbücher (so fern sie noch ausgeliefert wurden) immer schlechter. Und wer kämpft sich schon durch die CPU-View beim Debuggen durch? |
Re: Wann ein "inherited" im Constructor ?
Zitat:
|
Re: Wann ein "inherited" im Constructor ?
Das ist nicht so ganz einfach mit dem Verstecken der Konstruktoren. Siehe meinen TJvHidDeviceController.
Ein privater Konstruktor verbirgt eben nicht den von TObject geerbten Konstruktor. Ich habe deshalb den Konstruktor ueberschrieben und mittels Exception unbrauchbar gemacht und einen anders benannten privaten Konstruktor eingefuehrt. |
Re: Wann ein "inherited" im Constructor ?
Zitat:
Du kannst beim Überschreiben keine Methode in eine geringere Sichtbarkeit überführen. Zitat:
Zitat:
Vielen Dank an jbg und allen anderen für die Erklärungen. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 10:22 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz