Beispiel:
Code: Alles auswählen
type
tmyobject = class(tobject)
public
field1: integer;
end;
[...]
myobject:= tmyobject.create;
myobject.destroy;
tmyobject hat kein create constructor, also wird tobject.create aufgerufen:
Alle constructor Prozeduren rufen zuerst newinstance auf, wo der Speicher reserviert und initialisiert wird. Dieser Aufruf ist im Quellcode nicht sichtbar sondern wird vom Compiler eingefügt. Die normale newinstance Funktion:
Code: Alles auswählen
class function TObject.NewInstance : tobject;
var
p : pointer;
begin
getmem(p, InstanceSize);
if p <> nil then
InitInstance(p);
NewInstance:=TObject(p);
end;
Instancesize liefert die Grösse des zu reservierenden Speichers aus der classinfo von tmyobject:
Code: Alles auswählen
class function TObject.InstanceSize : SizeInt;
begin
InstanceSize:=pSizeInt(pointer(self)+vmtInstanceSize)^;
end;
Initinstance füllt den reservierten Speicher mit Nullen und initialisiert allfällige interface Tabellen.
Nach der Rückkehr von create ruft der Compiler AfterConstruction auf:
tmyobject hat keinen destroy destructor, also wird tobject.destroy aufgerufen:
Alle destructor Prozeduren rufen zuerst BeforeDestruction auf, der Aufruf ist wiederum nicht sichtbar sonder wird vom Compiler eingebaut.
Nach der Rückkehr von destroy kommt FreeInstance:
Code: Alles auswählen
procedure TObject.FreeInstance;
begin
CleanupInstance;
FreeMem(Pointer(Self));
end;
Cleanupinstance ruft finalize für alle eventuell vorhandene felder mit dynamisch alloziertem Speicher (ansistring, dynamische Arrays) auf und ruft release für COM-Interface Felder auf, danach wird der Speicher freigegeben.
Sag jetzt bloss nicht, du hättest es gar nicht so genau wissen wollen...
Martin