Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Algorithmen, Datenstrukturen und Klassendesign (https://www.delphipraxis.net/78-algorithmen-datenstrukturen-und-klassendesign/)
-   -   Delphi nach inherited Create ist self=nil (https://www.delphipraxis.net/184643-nach-inherited-create-ist-self%3Dnil.html)

Captnemo 11. Apr 2015 18:49

nach inherited Create ist self=nil
 
Hi,

ich habe eine Klasse, in der ich den Constructor überschreibe, und zwei eigene benutzen möchte.
(Nicht wundern, dass im Create noch nichts weiter drin ist. Kommt noch).

Deklaration:
Delphi-Quellcode:
    constructor Create; overload;
    constructor Create(Drucker: string; Kopien: Integer; KassenList: TKassenList; WarengruppenList: TWarengruppenList); overload;
die Constructoren:
Delphi-Quellcode:
constructor TDruckMonatsabschlussDetails.Create;
begin
  inherited Create;
end;

constructor TDruckMonatsabschlussDetails.Create(Drucker: string;
  Kopien: Integer; KassenList: TKassenList;
  WarengruppenList: TWarengruppenList);
begin
  inherited Create;
  self.FDrucker:=Drucker;
  self.FKopien:=Kopien;
  self.FKassenList:=KassenList;
  self.FWarengruppenList:=WarengruppenList;
end;
Wenn ich jetzt den Constructor mit den Parametern aufrufe, ist nach der Zeile "inherited Create" das Self=Nil, was ich mir nicht erklären kann. In der Zeile "inherited Create" erhalte ich jedoch keine Fehlermeldung.

Andere Klassen, wo ich es genauso gemacht habe laufen jedoch. Woran kann mein Fehler liegen?

BadenPower 11. Apr 2015 19:19

AW: nach inherited Create ist self=nil
 
Zitat:

Zitat von Captnemo (Beitrag 1297253)
Hi,

ich habe eine Klasse, in der ich den Constructor überschreibe, und zwei eigene benutzen möchte.
(Nicht wundern, dass im Create noch nichts weiter drin ist. Kommt noch).

Deklaration:
Delphi-Quellcode:
    constructor Create; overload;
    constructor Create(Drucker: string; Kopien: Integer; KassenList: TKassenList; WarengruppenList: TWarengruppenList); overload;

Du überschreibst den Constuctor ja nicht, sondern Du überlädst in nur.

Zum Überschreiben override benutzen:
Delphi-Quellcode:
constructor Create; override;

himitsu 11. Apr 2015 19:28

AW: nach inherited Create ist self=nil
 
Wie hast du denn dieses Create aufgerufen? :stupid:

BadenPower 11. Apr 2015 19:34

AW: nach inherited Create ist self=nil
 
Und von welcher Klasse ist die Klasse "TDruckMonatsabschlussDetails" abgeleitet?

Captnemo 11. Apr 2015 21:49

AW: nach inherited Create ist self=nil
 
@Himitsu: Danke, das war der Hinweis den ich brauchte.
Ich hab statt

Ausdruck:=TDruckMonatsabschlussDetails.Create(...)

Audruck.Create(...)

aufgerufen, was natürlich mangels Zuweisung nicht funktioniert. Eigentlich wär bei sowas auch eine Exception schon beim Inherited Create auch ganz toll.
Ein blöder Fehler, der mir eigentlich nicht mehr passieren sollte. Aber trotzdem passiert's. Muss am Alter liegen.

Popov 11. Apr 2015 22:03

AW: nach inherited Create ist self=nil
 
Zitat:

Zitat von Captnemo (Beitrag 1297268)
Eigentlich wär bei sowas auch eine Exception schon beim Inherited Create auch ganz toll.

Warum? Ich weiß zwar nicht von welcher Klasse du deine Klasse ableitest, aber wenn es von TObject abgeleitet ist, da ist nichts. Create von TObject ist leer. Man ruft es mit inherited auf, weil es üblich ist, aber im Grunde könnte man es sich sparen. Aber hören wir da auf Himitsu, der da sagte: man sollte es trotz dem aufrufen, es könnte ja eines Tages da was stehen.

Also, aufruf von Nichts erzeugt kein Exception.

jfheins 11. Apr 2015 22:08

AW: nach inherited Create ist self=nil
 
Eigentlich wäre es schön, wenn sowas (aufrufen von .Create auf eine Instanz) nen Compilerfehler erzeugt - aber ich glaube die Diskussion hatten wir schonmal :stupid:

Könnte man lösen, indem .Create eine Klassenmethode ist und keine Instanzmethode. Ist aber wohl historisch so gewachsen...

Ja, gab es schon mal. Siehe hier: http://www.delphipraxis.net/179403-v...create%3B.html

Bernhard Geyer 11. Apr 2015 22:24

AW: nach inherited Create ist self=nil
 
create ist ja eine Klassenmethode. Und eine Klassenmethode darf immer auch von ener instanz aufgerufen werden.
Eine Warnung "variable ist nicht initialisiert" wäre möglich. Aber eine solche Warnung wäre ja bei einer Klassenmethode nicht nötig, also dann eher ein Hinweis

himitsu 11. Apr 2015 22:53

AW: nach inherited Create ist self=nil
 
Nein, Create ist eine Funktion (mit Zusatzfuntion, wenn als Klassenmethode aufgerufen) und das ist auch richtig so, aber es wäre besser, wenn der Compiler endlich mal den Functionsaufruf "melden/hinweisen" würde, aber natürlich abschaltbar, so wie z.B. das reintroduce beim Verdecken.

Hier mal die Kurzfassung einer bekannten Delphiprozedur, die den Fehler behebt, daß Idioten im Create auf die globale Form-Variable zugreifen, welche ja eigentlich erst nach dem Erstellen zugewiesen würde.
NewInstance erstellt die Instanz (Self <> nil) und der Constructor initialisiert nur den Inhalt.
Delphi-Quellcode:
procedure TApplication.CreateForm(InstanceClass: TComponentClass; var Reference);
var
  Instance: TComponent;
begin
  Instance := TComponent(InstanceClass.NewInstance);
  TComponent(Reference) := Instance;
  try
    Instance.Create(Self);
  except
    TComponent(Reference) := nil;
    Instance := nil;
    raise;
  end;
end;
Ich würde mir wünschen, wenn auch der Form-Loader (TReader) das nutzen würde, damit man im Create bereits den ComponentState und da vorallem csLoading, csReading und csDesigning direkt benutzen könnte und sich nicht über den Owner das raussuchen müsste.

Und hier mal das, was Delphi in Wirklichkeit bei Constructor, Destructor und Free macht.
Delphi-Quellcode:
// O := TObject.Create(...);

{ System._ClassCreate System._AfterConstruction }
Temp := TObject.NewInstance;
try
  Temp.Create(...); // Methodenaufruf
  Temp.AfterConstruction;
except
  Temp.Destroy;
  raise;
end;
O := Temp;
Delphi-Quellcode:
// O.Free;

if Assigned(O) then // O = Self
  O.Destroy;
Delphi-Quellcode:
// O.Destroy;

{ System._ClassDestroy System._BeforeDestruction }
try
  O.BeforeDestruction;
  O.Destroy; // Methodenaufruf
finally
  O.FreeInstance;
end;
:!: Gezeigte Codes sind die Kurzfassungen der Hauptfunktion der genannten Beispiele. (außer beim Free, welches wirklich den kompletten Code darstellt)

Captnemo 11. Apr 2015 23:01

AW: nach inherited Create ist self=nil
 
Ja, ist von TObject abgeleitet.

Gerade weil es so ein alter Hut ist, sollte mir so ein doofer Fehler nicht mehr passieren. Tut er aber, und das gibt mir zu denken :wink:


Alle Zeitangaben in WEZ +1. Es ist jetzt 06:03 Uhr.
Seite 1 von 2  1 2      

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