Destruktor automatisch aufrufen beim verlassen der Procdure

Für Fragen zur Programmiersprache auf welcher Lazarus aufbaut
Antworten
joe
Beiträge: 37
Registriert: Fr 28. Mai 2010, 15:47

Destruktor automatisch aufrufen beim verlassen der Procdure

Beitrag von joe »

Ich möchte gerne (z.B.) eine Klasse implementieren, deren Konstruktor automatisch beim verlassen der Procedure automatisch aufgerufen wird (oder noch besser beim verlassen des begin/end Blocks in dem das Create gerufen wurde).

Im Prinzip wird sowas ähnliches ja beim Datentyp String gemacht. Der Compiler garantiert her, dass der Speicher stets korrekt freigegeben wird - egal ob die Procedure via exit oder aufgrund einer Exception verlassen wird. Und noch mehr: Wenn ich ein String als Member einer eigenen Klasse verwende, dann muss ich mich im D'tor meiner Klasse nicht um die Freigabe des String kümmern.

Kann ich mir sowas wie den Datentyp String auch selbst, also als eigenen Datentyp (z.B. MyString) definieren oder ist die damit verbundene Funktionalität allein dem Compiler vorbehalten?
Wäre für mich auch akzeptabel, wenn das nur mit Ref-Counted Instanzen geht.

(Überall und immer try/finally zu schreiben wäre sicherlich eine Alternative, aber genau das will ich vermeiden wegen des Fehlerpotentials.)

Socke
Lazarusforum e. V.
Beiträge: 3158
Registriert: Di 22. Jul 2008, 19:27
OS, Lazarus, FPC: Lazarus: SVN; FPC: svn; Win 10/Linux/Raspbian/openSUSE
CPU-Target: 32bit x86 armhf
Wohnort: Köln
Kontaktdaten:

Re: Destruktor automatisch aufrufen beim verlassen der Procd

Beitrag von Socke »

joe hat geschrieben:Ich möchte gerne (z.B.) eine Klasse implementieren, deren Konstruktor automatisch beim verlassen der Procedure automatisch aufgerufen wird (oder noch besser beim verlassen des begin/end Blocks in dem das Create gerufen wurde).

Free Pascal unterstützt keine Variablen in einzelnen Blöcken. Daher können Variablen vom Compiler nur am Anfang (Initialisierung) bzw. am Ende (Finalisierung) einer Prozedur bearbeitet werden. Dazwischen musst du es selbst machen.

joe hat geschrieben:(Überall und immer try/finally zu schreiben wäre sicherlich eine Alternative, aber genau das will ich vermeiden wegen des Fehlerpotentials.)

Der Compiler macht nichts anderes, nur siehst du es nicht. In komplexen Anwendungsfällen ist es in der Regel hilfreicher, genau festzulegen, welches Objekt wo erstellt wird und wann es (wo, von wem) wieder freigegeben wird. Da das in Pascal schon immer bevorzugt wurde (mit Pascal sollte das saubere Programmieren gelehrt werden), gibt es auch keinen Garbage-Collector oder Ähnliches, was im Hintergrund aufräumt.

joe hat geschrieben:Wäre für mich auch akzeptabel, wenn das nur mit Ref-Counted Instanzen geht.

Dann musst du mit referenzgezählten Interfaces arbeiten:

Code: Alles auswählen

type
{$INTERFACES COM} // COM-Interfaces sind referenzgezählt
  imyintf = interface
    procedure myproc;
  end;
 
  // von TInterfacedObject ableiten, da hier schon die Referenzzählung von IInterface implementiert ist.
  tmyclass = class(TInterfacedObject, imyintf)
    procedure myproc;
  end;
 
var
  i: imyintf;  // Variable vom Interface-Typen
begin
  i := tymclass.Create;
  i.myproc;
end;
MfG Socke
Ein Gedicht braucht keinen Reim//Ich pack’ hier trotzdem einen rein

Antworten