Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Algorithmen, Datenstrukturen und Klassendesign (https://www.delphipraxis.net/78-algorithmen-datenstrukturen-und-klassendesign/)
-   -   TObjectList<TMyClass> create und inherited (https://www.delphipraxis.net/199595-tobjectlist-tmyclass-create-und-inherited.html)

bcvs 5. Feb 2019 07:17

TObjectList<TMyClass> create und inherited
 
Hallo zusammen,

ich bin da auf eine Sache gestoßen und würde gerne wissen, warum das so ist:

Ich habe eine Klasse:

Delphi-Quellcode:
TMyObjectList = class(TObjectList<TMyObject>);
private
...
public
  constructor Create;
  destructor Destroy; override;
end;
Der constructor sah bisher so aus:
Delphi-Quellcode:
constructor TMyObjectList.Create;
begin
  inherited; // <- ohne Create
  // Weiteres Zeugs
end;
Dann habe ich festgestellt, dass das OwnsObjects dieser TMyObjectList false ist, obwohl es ja defaultmäßig true sein sollte. Deshalb gab es jede Menge Speicherlecks. Das Create der Basisklasse wird offensichtlich nicht aufgerufen.

Wenn ich dann das Create so ändere, ist alles in Ordnung:
Delphi-Quellcode:
constructor TMyObjectList.Create;
begin
  inherited Create; // <- mit Create
  // Weiteres Zeugs
end;
Ich hatte bisher immer gedacht, das man das Create nach dem inherited auch weglassen könnte. Bei Override-Methoden ist das ja auch so.
Im Constructor wird aber der originale Contructor anscheinend nicht aufgerufen, wenn man nur inherited schreibt. Es gibt aber auch keine Compilerwarnung. Da muss man schon aufpassen, dass man da nicht drüber stolpert.

Schokohase 5. Feb 2019 07:32

AW: TObjectList<TMyClass> create und inherited
 
Das ist doch problemlos möglich, aber eben so
Delphi-Quellcode:
type
  TMyObjectList = class(TObjectList<TObject>)
  public
    constructor Create(AOwnsObjects: Boolean = True);
  end;

constructor TMyObjectList.Create(AOwnsObjects: Boolean);
begin
  inherited;
end;

bcvs 5. Feb 2019 09:12

AW: TObjectList<TMyClass> create und inherited
 
Das kompiliert erst garnicht:

Delphi-Quellcode:
constructor TMyObjectList.Create(AOwnsObjects: Boolean);
begin
  inherited; // <- Inkompatible Typen
end;
egal ob ich
Delphi-Quellcode:
Create(AOwnsObjects: Boolean)
oder
Delphi-Quellcode:
Create(AOwnsObjects: Boolean = True)
schreibe

ConnorMcLeod 5. Feb 2019 09:18

AW: TObjectList<TMyClass> create und inherited
 
Es gibt einen netten Leitspruch: immer, wenn Du mit "inherited" ohne Qualifizierung überschreibst, dann stirbt ein kleines Kätzchen.

Schokohase 5. Feb 2019 09:27

AW: TObjectList<TMyClass> create und inherited
 
Ich habe das mit 10.3 Rio ausprobiert und dort funktioniert es wunderbar.

peterbelow 5. Feb 2019 14:16

AW: TObjectList<TMyClass> create und inherited
 
Naja, was Du da machst ist den Constructor von TObjectlist<TMyObject> zu ersetzten. Das inherited ruft dann den Constructor in der Vererbungshierarchie auf, der keinen Parameter hat (den gibt es, nämlich den von TList<T>), und nicht den mit dem Parameter OwnsObjects: Boolean = true. Du mußt da explizit

inherited Create(true);

schreiben um den richtigen Constructor zu erwischen.

bcvs 6. Feb 2019 06:53

AW: TObjectList<TMyClass> create und inherited
 
Das ist aber trotzdem etwas verwirrend, denn

inherited create; (ohne Parameter) ruft ja den richtigen Constructor auf, nur inherited; (ohne create) nicht.
Liegt es vielleicht daran, dass das
Delphi-Quellcode:
TObjectlist<TMyObject>.Create(OwnsObjects: Boolean = true);
schon einen Parameter hat, man den aber meistens weglässt, weil er per Default true ist?

bcvs 6. Feb 2019 07:31

AW: TObjectList<TMyClass> create und inherited
 
Um die Verwirrung komplett zu machen, habe ich das Ganze mal mit der nicht-generischen TObjectList getestet:

Delphi-Quellcode:
TMyObjectList = class(TObjectList)
private
...
public
  constructor Create;
  destructor Destroy; override;
end;

constructor TMyObjectList.Create;
begin
  inherited; // <- ohne Create
  // Weiteres Zeugs
end;
Ergebnis: Das inherited; (ohne Create, ohne Parameter) ruft hier den richtigen Constructor auf und OwnsObjects ist true;

Wenn man in die Doku schaut, wird die Sache aber auch wieder etwas klarer:

Die nicht-generische TObjectList hat ein Create ohne Parameter:
Delphi-Quellcode:
constructor Create; overload;
constructor Create(AOwnsObjects: Boolean); overload;
Die generische TObjectList hat das nicht:
Delphi-Quellcode:
constructor Create(AOwnsObjects: Boolean = True); overload;
constructor Create(const AComparer: IComparer<T>; AOwnsObjects: Boolean = True); overload;
constructor Create(const Collection: TEnumerable<T>; AOwnsObjects: Boolean = True); overload;
Es ist also offensichtlich ein Unterschied, ob es ein Create ohne Parameter gibt oder ob man bei einem Create(AOwnsObjects: Boolean = True) den Parameter weglässt.


Alle Zeitangaben in WEZ +1. Es ist jetzt 18:24 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz