Autor Beitrag
manuthie
Hält's aus hier
Beiträge: 14



BeitragVerfasst: Mi 05.02.03 13:08 
Hallo,

Kann mir vielleicht mal jemand erklähren, warum der constructor Create des Objektes TObject statisch deklariert ist, wohingegen der destructor Destroy virtuell ist?
Würde mich einfach mal interessieren ...

mfg, Manuel
maximus
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 896

Win XP, Suse 8.1
Delphi 4/7/8 alles prof
BeitragVerfasst: Mi 05.02.03 14:08 
hi,

wenn du ein object erstellst, dann gibst du ja immer explizit die classe an, womit dann auch der konstruktor deiner neuen klasse ausgeführt wird. d.h. du kannst einfach das TObject.create verdecken, ohne schwierigkeiten zu bekommen. Musst nochnichtmal inherited machen, weil nichts im TObject.create drin steht.

Beim destruktor ist die klasse nicht immer klar, d.h er wird dann ausgeführt auch wenn du dich nicht explizit auf die klasse beziehst!

hoffe das hilft dir :)

mfg mx
Udontknow
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 2596

Win7
D2006 WIN32, .NET (C#)
BeitragVerfasst: Mi 05.02.03 15:19 
Jaja, das ist schon richtig, allerdings führen doch fast alle Nachfahren von TObject den Konstructor als virtuell ein und übersteuern ihn dann doch immer! Warum also nicht sofort einen virtuellen Konstruktor?

Cu,
Udontknow
maximus
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 896

Win XP, Suse 8.1
Delphi 4/7/8 alles prof
BeitragVerfasst: Mi 05.02.03 16:00 
weil ihn niemand braucht, da sowieso nix drinne steht. das wär halt nur verschwendung. alle folgenden kunstruktoren haben meist funktionen zu erfüllen und wenn mann dann zB auto-complete macht ist inherited schon mit drinn. denke ich.

mfg maximus
Udontknow
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 2596

Win7
D2006 WIN32, .NET (C#)
BeitragVerfasst: Mi 05.02.03 16:15 
Hihi, da kann man dann trotzdem fragen: Wieso statisch und nicht virtuell? Wieso überhaupt? :wink:

Cu,
Udontknow
maximus
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 896

Win XP, Suse 8.1
Delphi 4/7/8 alles prof
BeitragVerfasst: Mi 05.02.03 17:12 
*lol* gute frage...der vollständigkeit halber! ausserdem man braucht ja für TObject auch'nen konstruktor, um es überhaupt erstellen zu können.
AndyB
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 1173
Erhaltene Danke: 14


RAD Studio XE2
BeitragVerfasst: Mi 05.02.03 20:16 
Udontknow hat folgendes geschrieben:
allerdings führen doch fast alle Nachfahren von TObject den Konstructor als virtuell ein
´
Das sind nicht alle Klassen, sondern hauptsächlich TComponent. Und ein virtueller Konstruktor hat eine ganz andere Bedeutung als eine virtuelle Methode oder ein virtueller Destruktor.


Der virtuelle Konstruktor wird für Klassentypen eingesetzt:
ausblenden Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
type
  TComponentClass = class of TComponent;

function CreateInstance(ComponentClass: TComponentClass): TComponent;
begin
  Result := ComponentClass.Create(nil);
end;

var comp: TComponent;
begin
  comp := CreateInstance(TForm); // neues Formular erzeugen
  TForm(comp).Show;

  comp := CreateInstance(TButton); // neuen Button erzeugen
  TButton(comp).Click;
end;

Wenn nun der Konstruktor von TComponent statisch wäre, so würde immer TComponent.Create() aufgerufen, egal welche Klasse man an CreateInstance übergibt. Dabei würde comp keine TForm-Instanz, sondern eine TComponent-Instanz sein.

_________________
Ist Zeit wirklich Geld?
manuthie Threadstarter
Hält's aus hier
Beiträge: 14



BeitragVerfasst: Mi 05.02.03 20:46 
Naja, mir ging es eigentlich in der Hauptsache darum, daß nix verloren geht wenn ich in einer von TObject abgeleiteten Klasse "Create" Verdecke ...
Sehe ich das also richtig, daß ich mir in diesem Fall auch "inherited Create" sparen kann?

mfg, Manuel
AndyB
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 1173
Erhaltene Danke: 14


RAD Studio XE2
BeitragVerfasst: Mi 05.02.03 21:08 
manuthie hat folgendes geschrieben:
Sehe ich das also richtig, daß ich mir in diesem Fall auch "inherited Create" sparen kann?

Nur wenn der Vorfahr TObject ist, und da macht man es (aus Gewohnheit) dann auch gleich mit. Ein Konstruktor reserviert ja nicht nur den Speicher, er initialisiert auch die Felder. Wenn du nun das inherited Create weg lässt, so kann der Vorfahrkonstruktor seine Felder nicht auf ihren Startwert setzen und das kann gravierende Auswirkungen haben.

ausblenden Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
TBase = class(TObject)
  Feld1: Integer;
  constructor Create;
end;

TDerived = class(TBase)
  Feld2: string;
  constructor Create;
end;

constructor TBase.Create;
begin
  inherited Create;
  Feld1 := 10;
end;

constructor TDerived.Create;
begin
  inherited Create;
  Feld2 := IntToStr(Feld1);
end;

Wenn man nun bei TDerived.Create das inherited Create entfernt, so steht in Feld1 nicht die 10 und somit wird Feld2 auf einen nicht gewünschten Wert gesetzt.
Bei diesem Beispiel ist die Auswirkung nicht besonders gravierend, aber wenn man sich die Felder von TWinControl anschaut kann das schon zu Schutzverletzungen führen.

_________________
Ist Zeit wirklich Geld?
manuthie Threadstarter
Hält's aus hier
Beiträge: 14



BeitragVerfasst: Mi 05.02.03 21:16 
.. ich meinte schon einen direkten Abkömmling von TObject. Aber im Zweifelsfall tut es ja auch nicht weh, es überflüssigerweise hinzuschreiben.

Danke für die Aufklährung
Udontknow
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 2596

Win7
D2006 WIN32, .NET (C#)
BeitragVerfasst: Mi 05.02.03 22:25 
@AndyB:

Ich kenne doch recht viele Klassen, die direkt von TObject abstammen und den Konstruktor wie oben genannt als virtuell deklarieren. Ich selber mache das auch in eigenen Listenobjekten etc., also in den Fällen, wo ich zum Beispiel eine Eigenschaft Owner benötige, TComponent aufgrund seiner Streaming- und Filing-Funktionen aus Geschwindigkeitsgründen aber ausscheidet (schon mal 10000 TObject-Instanzen erstellt und verworfen und das gleiche auch mal mit TComponent gemacht? Der Unterschied ist immens!).

Cu, :)
Udontknow
AndyB
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 1173
Erhaltene Danke: 14


RAD Studio XE2
BeitragVerfasst: Mi 05.02.03 22:59 
Udontknow hat folgendes geschrieben:
Ich kenne doch recht viele Klassen, die direkt von TObject abstammen und den Konstruktor wie oben genannt als virtuell deklarieren.

So viele sind mir da jetzt gar nicht eingefallen: TComponent, TCollectionItem, TGraphics und ein paar weitere. Die selbst kreierten sind natürlich ausgeschlossen.


Zitat:
TComponent aufgrund seiner Streaming- und Filing-Funktionen aus Geschwindigkeitsgründen aber ausscheidet (schon mal 10000 TObject-Instanzen erstellt und verworfen und das gleiche auch mal mit TComponent gemacht? Der Unterschied ist immens!).

Wenn man das Freigeben weg lässt, so geben sich die Konstruktoren nichts. Hingegen die Destruktoren unterscheiden sich gewaltig.

_________________
Ist Zeit wirklich Geld?
Udontknow
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 2596

Win7
D2006 WIN32, .NET (C#)
BeitragVerfasst: Mi 05.02.03 23:54 
Zitat:
Wenn man das Freigeben weg lässt, so geben sich die Konstruktoren nichts. Hingegen die Destruktoren unterscheiden sich gewaltig.


Hihi... Wenn man das Freigeben weg lässt, hat man früher oder später ein Problem... :wink: Na, der Destruktor von TComponent ist eben ein Grund, Dinge wie Eigentümerschaft lieber in TObject zu regeln (und den Konstruktor mit einem Parameter Owner zu versehen).

Ich denke, wir sind uns einig.

Gute Nacht, :)
Udontknow