OOP Destructor wird nicht aufgerufen..

Für Fragen zur Programmiersprache auf welcher Lazarus aufbaut
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: OOP Destructor wird nicht aufgerufen..

Beitrag von mse »

Damit die Warnung unterdrückt wird. Der ursprüngliche tcomponent.create() constructor soll nicht verwendet werden, darum ist die "hides a virtual procedure" (oder so) Warnung falsch.

Benutzeravatar
m.fuchs
Lazarusforum e. V.
Beiträge: 2822
Registriert: Fr 22. Sep 2006, 19:32
OS, Lazarus, FPC: Winux (Lazarus 2.0.10, FPC 3.2.0)
CPU-Target: x86, x64, arm
Wohnort: Berlin
Kontaktdaten:

Re: OOP Destructor wird nicht aufgerufen..

Beitrag von m.fuchs »

mse hat geschrieben:Der ursprüngliche tcomponent.create() constructor soll nicht verwendet werden[...]
Aber warum?
Software, Bibliotheken, Vorträge und mehr: https://www.ypa-software.de

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: OOP Destructor wird nicht aufgerufen..

Beitrag von mse »

Weil "tfindinfilepagefo" ohne "findinfo" nicht funktioniert.
Ein ähnlicher Umstand ist bei "ttreelistitem".
https://gitlab.com/mseide-msegui/mseide ... anodes.pas
Ein "ttreelistitem" erbt von "tlistitem" den virtuellen constructor

Code: Alles auswählen

 
tlistitem = class(tnullinterfacedobject)
...
   constructor create(const aowner: tcustomitemlist); virtual;
 
welcher für die meisten "tlistitem" Nachkommen durch Überschreiben ("override") angepasst werden kann.
"ttreelistitem" braucht nun eine andere Umgebung, daher der neue virtuelle constructor

Code: Alles auswählen

 
   constructor create(const aowner: tcustomitemlist = nil;
              const aparent: ttreelistitem = nil); reintroduce; virtual;
 
welcher für die meisten "ttreelistitem" Nachkommen durch Überschreiben angepasst werden kann.
Für spezialisierte "ttreelistitem" Nachkommen ist manchmal wieder ein constructor mit anderen Parametern notwendig:
https://gitlab.com/mseide-msegui/mseide ... rowser.pas
https://gitlab.com/mseide-msegui/mseide ... eeform.pas

Code: Alles auswählen

 
 ttreelistedititem = class(ttreelistitem)
  private
   factiveindex: integer;
   function getactiveindex: integer;
  public
   constructor create(const aowner: tcustomitemlist = nil;
              const aparent: ttreelistitem = nil); override;
   procedure assign(source: ttreeitemeditlist); overload;
       //source remains owner of items, parent of items is unchanged
   function add(const aitem: ttreelistedititem): integer; overload;
                   //returns index, nil ignored
   procedure add(const aitems: treelistedititemarty); overload;
   function add(const itemclass: treelistedititemclassty = nil):
                                             ttreelistedititem; overload;
   procedure add(const acount: integer; 
               const itemclass: treelistedititemclassty = nil); overload;
   procedure add(const captions: array of msestring; 
               const itemclass: treelistedititemclassty = nil); overload;
   property activeindex: integer read getactiveindex;
   function endtreerow: integer; 
                //returns index of last row of tree
   function editwidget: ttreeitemedit;
   procedure activate;
 end;
...
 
 tprojectnode = class(ttreelistedititem)
   fkind: projectnodety;
   ferror: boolean;
  protected
   function getcurrentimagenr: integer; virtual;
   function compare(const r: tlistitem;
                          const acasesensitive: boolean): integer; override;
  public
   constructor create(const akind: projectnodety); reintroduce; <<<<----
 end;
 

Benutzeravatar
m.fuchs
Lazarusforum e. V.
Beiträge: 2822
Registriert: Fr 22. Sep 2006, 19:32
OS, Lazarus, FPC: Winux (Lazarus 2.0.10, FPC 3.2.0)
CPU-Target: x86, x64, arm
Wohnort: Berlin
Kontaktdaten:

Re: OOP Destructor wird nicht aufgerufen..

Beitrag von m.fuchs »

Aber funktioniert dann das Streaming der Komponenten noch? Deswegen ist doch der Constructor von TComponent als virtual deklariert.
Software, Bibliotheken, Vorträge und mehr: https://www.ypa-software.de

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: OOP Destructor wird nicht aufgerufen..

Beitrag von mse »

Ja, vorausgesetzt man macht in ReadState(), DefineProperties()... alles notwendige. Es gibt auch Fälle wo Komponenten nicht gestreamt werden müssen.

Michl
Beiträge: 2511
Registriert: Di 19. Jun 2012, 12:54

Re: OOP Destructor wird nicht aufgerufen..

Beitrag von Michl »

Entprechend der vorher geführten Diskussion hätte ich hier

Code: Alles auswählen

type
  TCalc = Class
    ID: Integer;
    Data: Array of Integer;
  end;
 
  { TCalcList }
 
  TCalcList = Class( specialize TFPGList<TCalc> )
    procedure Delete(Index: Integer);  // <-- hier
    procedure Clear;                   // <-- und hier
  end;  
eine Compiler-Warnung erwartet, dass ich Methoden überschreibe. MMn hätte ich dahinter ein "reintroduce" schreiben müssen, der Compiler akzeptiert dies aber mit und ohne dies.

Was ist denn eure Meinung dazu?

Rest vom Code:

Code: Alles auswählen

uses ..., fgl;
... 
procedure TCalcList.Delete(Index: Integer);
begin
  Self[Index].Free;
  inherited Delete(Index);
end;
 
procedure TCalcList.Clear;
begin
  while Count > 0 do
    Delete(Count - 1);
end;   

Code: Alles auswählen

type
  TLiveSelection = (lsMoney, lsChilds, lsTime);
  TLive = Array[0..1] of TLiveSelection;  

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: OOP Destructor wird nicht aufgerufen..

Beitrag von mse »

Michl hat geschrieben: Was ist denn eure Meinung dazu?
Finger weg von Generics. ;-)

Michl
Beiträge: 2511
Registriert: Di 19. Jun 2012, 12:54

Re: OOP Destructor wird nicht aufgerufen..

Beitrag von Michl »

:) , zumindest scheint es wirklich an den Generics zu liegen. Nehme ich eine TObjectList, wird dort diese Warnung gezeigt.

Kannst du deine Meinung auch noch untermauern (außer, dass sie noch nicht vollständig funktionieren), ich finde den Dirketzugriff auf Items in der Generischen Liste sehr schön. Bei einer TObjectList muss ich bei jedem Zugriff casten.

Code: Alles auswählen

type
  TLiveSelection = (lsMoney, lsChilds, lsTime);
  TLive = Array[0..1] of TLiveSelection;  

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: OOP Destructor wird nicht aufgerufen..

Beitrag von mse »

Die sind im Compiler sehr schwierig zu implementieren und belasten auch generic-freie Kompilierungen. Ich bezweifle ob sie jemals 100% funktionieren werden.
Dann erweitern sie den Sprachumfang, das gefällt mir nicht. Meiner Meinung nach sollte die Zahl der Sprachelemente so klein wie möglich sein, siehe auch die Entwicklungsziele von MSElang.
Im Einsatz sind sie problematisch, da sie häufig unnötig code duplizieren. Der Compiler könnte da zwar optimierend eingreifen, dann wird es aber noch komplizierter.
Zu guter letzt sind sie selten wirklich notwendig. Das type casten bei Listen kann man auch durch eine spezialisierte abgeleitete Klasse vermeiden, MSEgui verwendet das Verfahren z.B. in den verschiedenen tdatalist und trecordlist Varianten (lib/common/kernel/msedatalist.pas, lib/common/kernel/mselist.pas).

marcov
Beiträge: 1102
Registriert: Di 5. Aug 2008, 09:37
OS, Lazarus, FPC: Windows ,Linux,FreeBSD,Dos (L trunk FPC trunk)
CPU-Target: 32/64,PPC(+64), ARM
Wohnort: Eindhoven (Niederlande)

Re: OOP Destructor wird nicht aufgerufen..

Beitrag von marcov »

mse hat geschrieben:Die sind im Compiler sehr schwierig zu implementieren und belasten auch generic-freie Kompilierungen. Ich bezweifle ob sie jemals 100% funktionieren werden.
Dann erweitern sie den Sprachumfang, das gefällt mir nicht. Meiner Meinung nach sollte die Zahl der Sprachelemente so klein wie möglich sein, siehe auch die Entwicklungsziele von MSElang.
Im Einsatz sind sie problematisch, da sie häufig unnötig code duplizieren. Der Compiler könnte da zwar optimierend eingreifen, dann wird es aber noch komplizierter.
Zu guter letzt sind sie selten wirklich notwendig. Das type casten bei Listen kann man auch durch eine spezialisierte abgeleitete Klasse vermeiden, MSEgui verwendet das Verfahren z.B. in den verschiedenen tdatalist und trecordlist Varianten (lib/common/kernel/msedatalist.pas, lib/common/kernel/mselist.pas).
Also, Generics sind schlecht weil zie Code duplizieren, aber die Lösung ist Code duplizieren durch Klasse ableitung? Merkwürdig.

P.s. Die constraints von .NET/Delphi generics sind dafür entworfen Code duplizieren für basis Container Typen zu vermeiden. Sie vermeiden die Falle von C++ Token Replay mit ein mehr Deklaratives Modell. Das hat auch einige Nachteile (speziell
für Valuetypes), aber Code Duplication ist nicht dabei.

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: OOP Destructor wird nicht aufgerufen..

Beitrag von mse »

marcov hat geschrieben: Also, Generics sind schlecht weil zie Code duplizieren, aber die Lösung ist Code duplizieren durch Klasse ableitung? Merkwürdig.
Da wird nur das dupliziert was dupliziert werden muss und man weiss genau was man tut.
Die pointer setter-getter Methoden z.B., die lediglich zur semantischen Typenkonvertierung dienen, enthalten keinen code und können von Compiler entfernt werden.
P.s. Die constraints von .NET/Delphi generics sind dafür entworfen Code duplizieren für basis Container Typen zu vermeiden. Sie vermeiden die Falle von C++ Token Replay mit ein mehr Deklaratives Modell. Das hat auch einige Nachteile (speziell
für Valuetypes), aber Code Duplication ist nicht dabei.
Aber weitere Aufblähung des Sprachumfanges, schauder, kotz, körbel.

marcov
Beiträge: 1102
Registriert: Di 5. Aug 2008, 09:37
OS, Lazarus, FPC: Windows ,Linux,FreeBSD,Dos (L trunk FPC trunk)
CPU-Target: 32/64,PPC(+64), ARM
Wohnort: Eindhoven (Niederlande)

Re: OOP Destructor wird nicht aufgerufen..

Beitrag von marcov »

mse hat geschrieben:
marcov hat geschrieben: Aber weitere Aufblähung des Sprachumfanges, schauder, kotz, körbel.
Ich konnte Argumenten akzeptieren um Generics um zu limitieren auf was für die wichtigste Containertypen nützlich ist. (zb eine Array/Liste, ein Hash- und ein Baum oder Ketten basiertes Typ). Bin nicht ganz damit einverstanden, aber konnte es schon akzeptieren.

Aber für jede Klasse die man mit ein Containertyp nutzt manuell Klasse ab zu leiten müssen, nur um der Kompilerbauer Arbeit zu sparen ist deutet IMHO auf ein grundsätzliches Ursache-Folge Konflikt.

Sprachen und Kompiler sind da um damit Kode zu schreiben. Der Sprachen und Kompiler ist kein ziel an sich. Ich schreiben darum Sprachen Minimaleismus nicht zu. (ich bin schon eimal in diesem Falle getreten mit Modula und Oberon Derivaten)

Michl
Beiträge: 2511
Registriert: Di 19. Jun 2012, 12:54

Re: OOP Destructor wird nicht aufgerufen..

Beitrag von Michl »

Also ist es eher eine Frage des Geschmacks. Danke für die Infos!

Code: Alles auswählen

type
  TLiveSelection = (lsMoney, lsChilds, lsTime);
  TLive = Array[0..1] of TLiveSelection;  

FPK
Beiträge: 65
Registriert: Mi 21. Mai 2008, 19:38
Wohnort: Erlangen

Re: OOP Destructor wird nicht aufgerufen..

Beitrag von FPK »

Michl hat geschrieben::) , zumindest scheint es wirklich an den Generics zu liegen. Nehme ich eine TObjectList, wird dort diese Warnung gezeigt.
Das liegt einfach daran, dass TObjectList.Clear virtual ist und TFPGList.Clear nicht.

Antworten