Destructor überschreiben oder nicht?

Rund um die LCL und andere Komponenten
Antworten
Giantics
Beiträge: 88
Registriert: Sa 3. Mär 2007, 13:46
OS, Lazarus, FPC: Winux (L 0.9.xy FPC 2.2.z)
CPU-Target: xxBit
Wohnort: Langenbrettach

Destructor überschreiben oder nicht?

Beitrag von Giantics »

Hallo,
soll/muss man den Destructor in einer neuen Klasse überschreiben?

Code: Alles auswählen

type
  TMyClass = class
  public
     Destructor Destroy;
  end;
Hier kommt immer die Compiler-Warnung: "An inherited method is hidden by destructor TMyClass.Destroy". Daher habe ich ein override hinter Destroy eingebaut.
Die Folge davon ist jedoch, dass beim Aufruf von Free einer Instanz von TMyClass folgender Fehler kommt: "Project blabla raised exception class 'External: SIGSEGV'.".
Wie macht mans richtig? Was hat es mit "reintroduce" auf sich?

Gruß
Thomas

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

Re: Destructor überschreiben oder nicht?

Beitrag von theo »

Override ist schon richtig, aber du musst dann auch inherited aufrufen:

Destructor TTest.Destroy;
begin
inherited Destroy
end;

Wenn du aber nichts machst im Destructor, brauchst du ihn auch nicht überschreiben.

Giantics
Beiträge: 88
Registriert: Sa 3. Mär 2007, 13:46
OS, Lazarus, FPC: Winux (L 0.9.xy FPC 2.2.z)
CPU-Target: xxBit
Wohnort: Langenbrettach

Beitrag von Giantics »

das "inherited Destroy" ist schon drin. Der Fehler kommt bei override trotzdem.

Code: Alles auswählen

TMP3Gain = class
  private
    FMP3GainProcess:TMP3GainProcess;
    FReady: Boolean;
    FSongItemList: TSongItemList;  
    // ...    
  public
    procedure Run;
    constructor Create;
    destructor Destroy; override; // reintroduce     
//...
 
constructor TMP3Gain.Create;
begin
  inherited Create;
  FReady := true;
  SongItem := nil;
  FSongItemList := TSongItemList.Create;
end;
 
destructor TMP3Gain.Destroy;
begin
  FMP3GainProcess.Free;
  FSongItemList.Free;
  inherited Destroy;
end;

Giantics
Beiträge: 88
Registriert: Sa 3. Mär 2007, 13:46
OS, Lazarus, FPC: Winux (L 0.9.xy FPC 2.2.z)
CPU-Target: xxBit
Wohnort: Langenbrettach

Beitrag von Giantics »

Habe den Fehler gefunden :-)
Das "FMP3GainProcess.Free;" im Destructor von TMP3Gain hat ihn ausgelöst. FMP3GainProcess wurde vorher schon eliminiert.
Allerdings wundert mich, dass es da trotzdem zu einem Fehler kommt. Free sollte ja dafür da sein, dass kein Fehler verursacht wird, auch wenn die Instanz nicht mehr exisiert. Oder irre ich mich da :?:

Danke euch!

Gruß
Thomas

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

Beitrag von theo »

Giantics hat geschrieben: Allerdings wundert mich, dass es da trotzdem zu einem Fehler kommt. Free sollte ja dafür da sein, dass kein Fehler verursacht wird, auch wenn die Instanz nicht mehr exisiert.
Ich glaube das klappt nur, wenn die Instanz vorher auf Nil gesetzt wurde.
Geht auch mit FreeAndNil();

monta
Lazarusforum e. V.
Beiträge: 2809
Registriert: Sa 9. Sep 2006, 18:05
OS, Lazarus, FPC: Linux (L trunk FPC trunk)
CPU-Target: 64Bit
Wohnort: Dresden
Kontaktdaten:

Beitrag von monta »

ich greif das Thema nochmal auf...weil ich mal nen ewiges Rätsel für mich klären will :lol:

Wann brauch ich nun eigentlich konkret ein inherited bzw. override?

Es gibt da ja verschiedenen Beispiele, mal mit, mal ohne.

Ich mach es bisher quasi immer so:

Code: Alles auswählen

TRTFWriter = class(TObject)
  private
    { private declarations }
    RTFText: TStrings;
  public
    { public declarations }
    constructor Create;
    destructor  Destroy;override;
  //....
  end;
 
 
implementation
 
{ TRTFWriter }
 
constructor TRTFWriter.Create;
begin
  RTFText := TStringList.Create;
end;
 
destructor TRTFWriter.Destroy;
begin
  inherited;
  RTFText.Free;
end;
wäre daran etwas falsch, bzw. warum wird bei obigem Beispiel eigentlich Create ebenfalls vererbt in meinem aber nicht? Bzw. müsste nicht auch create mit override und inherited versehen werden?
Johannes

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

Beitrag von theo »

Nein, denn überschreiben kannst du nur, was im Vorgänger mit virtual oder dynamic deklariert wurde. Da dein TRTFWriter von TObject abstammt, kannst und musst du den Konstruktor nicht "overriden".

Code: Alles auswählen

TObject = class
       public
          constructor Create;
          destructor Destroy;virtual;
Erst wenn ein Nachfahre was im Konstruktor macht, wird er ihn als Virtual Deklarieren. Dann kannst du ihn überschreiben und die Vorgänger-Prozedur mit inherited aufrufen.

Christian
Beiträge: 6079
Registriert: Do 21. Sep 2006, 07:51
OS, Lazarus, FPC: iWinux (L 1.x.xy FPC 2.y.z)
CPU-Target: AVR,ARM,x86(-64)
Wohnort: Dessau
Kontaktdaten:

Beitrag von Christian »

Problem bei Create ist schlichtweg das man wenn man etwas überschreiben will die selbe Deklaration braucht. Deswegen werden construktoren so gut wie nie überschreiben trotsdem mit inherited der Vorgänger aufgerufen.
W.m.k.A.h.e.m.F.h. -> http://www.gidf.de/

Benutzeravatar
af0815
Lazarusforum e. V.
Beiträge: 6770
Registriert: So 7. Jan 2007, 10:20
OS, Lazarus, FPC: FPC fixes Lazarus fixes per fpcupdeluxe (win,linux,raspi)
CPU-Target: 32Bit (64Bit)
Wohnort: Burgenland
Kontaktdaten:

Beitrag von af0815 »

Zudem auch noch als Anhaltspunkt:

*)im Construktor ZUERST inherited (wenn nötig), dann die eigenen Objekte etc. initialisieren.
*) Im Destruktor zuerst die eigenen Objekte freigeben und ZULETZT das Objekt mit inherited (wenn nötig).
Blöd kann man ruhig sein, nur zu Helfen muss man sich wissen (oder nachsehen in LazInfos/LazSnippets).

Christian
Beiträge: 6079
Registriert: Do 21. Sep 2006, 07:51
OS, Lazarus, FPC: iWinux (L 1.x.xy FPC 2.y.z)
CPU-Target: AVR,ARM,x86(-64)
Wohnort: Dessau
Kontaktdaten:

Beitrag von Christian »

Das kann man so nicht pauschalisieren das kommt drauf an was das Objekt macht. Beispiel: Ich hab eine Komponente die eine Schnittstelle abstahiert. Es gibt einen Vorfahren der für alle Schnittstellen gleich ist und z.b. im Construktor eine Log Datei anlegt und mit den ersten Daten füllt. Im nachfahren muss die Schnittstelle geöffnet und vorbereitet werden.

Nun setz dort mal das inheritet an den Anfang des 2. Constructors ...
W.m.k.A.h.e.m.F.h. -> http://www.gidf.de/

Benutzeravatar
af0815
Lazarusforum e. V.
Beiträge: 6770
Registriert: So 7. Jan 2007, 10:20
OS, Lazarus, FPC: FPC fixes Lazarus fixes per fpcupdeluxe (win,linux,raspi)
CPU-Target: 32Bit (64Bit)
Wohnort: Burgenland
Kontaktdaten:

Beitrag von af0815 »

Es steht darüber: 'als Anhaltspunkt'
Blöd kann man ruhig sein, nur zu Helfen muss man sich wissen (oder nachsehen in LazInfos/LazSnippets).

Antworten