Anfängerfrage? zu constructor und destructor

Für Fragen zur Programmiersprache auf welcher Lazarus aufbaut
Antworten
RSE
Beiträge: 462
Registriert: Mi 30. Jul 2008, 13:11
OS, Lazarus, FPC: WinXP SP3 (L 0.9.28.2 FPC 2.2.4)
CPU-Target: 32Bit
Kontaktdaten:

Anfängerfrage? zu constructor und destructor

Beitrag von RSE »

Schlimm, wenn man merkt, dass einem nach Jahren immernoch ein paar elementare Dinge nicht ganz 100%ig klar sind, und noch schlimmer, wenn man sie sich nicht selbst herleiten kann. Also hier meine Frage:

Brauche ich einen constructor bzw. einen destructor, wenn ich außer inherited; nichts reinzuschreiben habe? Oder ist es in diesen Fällen "legal" auf die geerbte Variante zurückzugreifen? Mir ist erst gestern klar geworden, dass man den constructor der Elternklasse bei jeder Ableitung einer Klasse verdeckt, während der destructor virtuell ist und overridden wird (schreckliches Denglisch, aber so ist es, denk ich, noch am verständlichsten ;-) ). Was mir dabei nicht so ganz klar ist: Wer reserviert den Speicher für meine neu eingeführten Felder (Variablen) in der Klasse, wenn ich den geerbten constructor verwende (der kennt ja nur die Elternklasse). Ebenso würde der geerbte destructor nur die Elemente der Elternklasse freigeben, wenn nicht noch andere Mechanismen greifen bzw. die Speicherreservierung und -Freigabe sowieso anders laufen.

EDIT: Gibt es dabei einen Unterschied zwischen den Modi ObjFPC und Delphi?
Seit er seinen neuen Computer hat, löst er alle Probleme, die er vorher nicht hatte!

Benutzeravatar
theo
Beiträge: 10869
Registriert: Mo 11. Sep 2006, 19:01

Re: Anfängerfrage? zu constructor und destructor

Beitrag von theo »

Die brauchst du nicht überschreiben, wenn du sie nicht benötigst. Das mit dem Speicher geht auch so klar.

RSE
Beiträge: 462
Registriert: Mi 30. Jul 2008, 13:11
OS, Lazarus, FPC: WinXP SP3 (L 0.9.28.2 FPC 2.2.4)
CPU-Target: 32Bit
Kontaktdaten:

Re: Anfängerfrage? zu constructor und destructor

Beitrag von RSE »

OK, thx
Seit er seinen neuen Computer hat, löst er alle Probleme, die er vorher nicht hatte!

pluto
Lazarusforum e. V.
Beiträge: 7192
Registriert: So 19. Nov 2006, 12:06
OS, Lazarus, FPC: Linux Mint 19.3
CPU-Target: AMD
Wohnort: Oldenburg(Oldenburg)

Re: Anfängerfrage? zu constructor und destructor

Beitrag von pluto »

Wer reserviert den Speicher für meine neu eingeführten Felder (Variablen) in der Klasse,
Für deine neu eingeführen Felder brauchst du natürlich ein constructor. Es sei denn du vergibst keine Standard Werte. Wobei bei einigen Datentypen kannst du auch das Schlüsselwort Default nutzen. Nutzt du z.b. eine TStringlist oder Tbitmap brauchst du oder währe es sinvoll wenn du ein constructor hättest. Je nach Aufgabe.

Die Primitiven Variablen wie String, Interger, und soweiter werden von Lazarus Vorinitialisiert. Allerdings kann es nicht schaden das selbst im constructor zu machen. Z.B. habe ich ein seltsames Verhalten bei Boolean entdeckt. z.B. bin ich davon ausgegangen das die Variable den wert False hat, wenn ich nichts anders sagen. Anscheint ist das nicht der Fall.
EDIT: Gibt es dabei einen Unterschied zwischen den Modi ObjFPC und Delphi?
Wenn du dich nur auf den Constructor und Destructor besiezst meines Wissens nicht. Der mir einzgiste Unterschied ist: Bei der Zuweisung von Events. Sonst ist mir noch keine Aufgefallen.
MFG
Michael Springwald

mse
Beiträge: 2013
Registriert: Do 16. Okt 2008, 10:22
OS, Lazarus, FPC: Linux,Windows,FreeBSD,(MSEide+MSEgui 4.6,git master FPC 3.0.4,fixes_3_0)
CPU-Target: x86,x64,ARM

Re: Anfängerfrage? zu constructor und destructor

Beitrag von mse »

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:

Code: Alles auswählen

constructor TObject.Create;
 
        begin
        end;
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:

Code: Alles auswählen

procedure TObject.AfterConstruction;
 
        begin
        end;
tmyobject hat keinen destroy destructor, also wird tobject.destroy aufgerufen:

Code: Alles auswählen

destructor TObject.Destroy;
 
        begin
        end;
Alle destructor Prozeduren rufen zuerst BeforeDestruction auf, der Aufruf ist wiederum nicht sichtbar sonder wird vom Compiler eingebaut.

Code: Alles auswählen

procedure TObject.BeforeDestruction;
 
        begin
        end;
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

RSE
Beiträge: 462
Registriert: Mi 30. Jul 2008, 13:11
OS, Lazarus, FPC: WinXP SP3 (L 0.9.28.2 FPC 2.2.4)
CPU-Target: 32Bit
Kontaktdaten:

Re: Anfängerfrage? zu constructor und destructor

Beitrag von RSE »

Das ist sehr aufschlussreich, mse, Besten Dank!

Was gibt es da für einen Unterschied, pluto? Die Events habe ich noch nicht eingebaut, aber dann weiß ich Bescheid, wenns soweit ist. Normal (= Modus Delphi ;-) ) kenne ich sowas:

Code: Alles auswählen

type
  TMyClass = class
    OnIrgendwas: procedure(Para: Integer) of Object;
...
procedure TMyClass.Test;
  begin
    if assigned OnIrgendwas then
      OnIrgendwas(5);
...
procedure Tuewas(i: Integer);
  begin
    ...
  end;
...
procedure Events_setzen;
  begin
    MyClass.Onirgendwas := @Tuewas;
...
Wie sähe das im Modus ObjFPC aus?
Seit er seinen neuen Computer hat, löst er alle Probleme, die er vorher nicht hatte!

Benutzeravatar
theo
Beiträge: 10869
Registriert: Mo 11. Sep 2006, 19:01

Re: Anfängerfrage? zu constructor und destructor

Beitrag von theo »

RSE hat geschrieben: Was gibt es da für einen Unterschied, pluto? Die Events habe ich noch nicht eingebaut, aber dann weiß ich Bescheid, wenns soweit ist. Normal (= Modus Delphi ;-) ) kenne ich sowas:
MyClass.Onirgendwas := @Tuewas;
Wie sähe das im Modus ObjFPC aus?
Normal ist nicht der Delphi Modus sondern der ObjFPC.

Das ist ObjFPC:
MyClass.Onirgendwas := @Tuewas;

Das ist Delphi:
MyClass.Onirgendwas := Tuewas;

RSE
Beiträge: 462
Registriert: Mi 30. Jul 2008, 13:11
OS, Lazarus, FPC: WinXP SP3 (L 0.9.28.2 FPC 2.2.4)
CPU-Target: 32Bit
Kontaktdaten:

Re: Anfängerfrage? zu constructor und destructor

Beitrag von RSE »

Hm, du hast tatsächlich Recht... Na dann ist ja alles wie gewohnt ;-) Danke allen!
Seit er seinen neuen Computer hat, löst er alle Probleme, die er vorher nicht hatte!

pluto
Lazarusforum e. V.
Beiträge: 7192
Registriert: So 19. Nov 2006, 12:06
OS, Lazarus, FPC: Linux Mint 19.3
CPU-Target: AMD
Wohnort: Oldenburg(Oldenburg)

Re: Anfängerfrage? zu constructor und destructor

Beitrag von pluto »

Ich glaube fast das war schon alles oder theo ? Jedenfalls sind mir bisher noch keine weiteren Unterschiede Aufgefallen. Außer bei der Zuweisung.
MFG
Michael Springwald

Benutzeravatar
theo
Beiträge: 10869
Registriert: Mo 11. Sep 2006, 19:01

Re: Anfängerfrage? zu constructor und destructor

Beitrag von theo »

ObjFPC ist strikter. Es gibt schon noch andere Unterschiede:
http://wiki.freepascal.org/User_Changes_2.2.0" onclick="window.open(this.href);return false;
http://www.nabble.com/Unexpected-duplic ... 25782.html" onclick="window.open(this.href);return false;

Antworten