Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Delphi Overload und Override für Constructor (https://www.delphipraxis.net/52667-overload-und-override-fuer-constructor.html)

meierotto 1. Sep 2005 10:20


Overload und Override für Constructor
 
Hallo,

ich befürchte, dass meine Frage schon in anderen Themen behandelt wurde,
hab aber in der Masse der Auswahl nichts finden können.

Mein Problem ist, dass ich einen Constructor als Overload sowie Override definieren möchte:

Delphi-Quellcode:
constructor Create(AOwner:TComponent); overload; override;
constructor Create(AOwner:TComponent;B,MB,PIN:String); overload; override;
Dabei wird mir aber die Fehlermeldung "Deklaration von 'Create' unterscheidet sich von vorheriger Deklaration" für die 2. Create-Deklaration angezeigt.
Was tu ich denn falsch machen?

:gruebel:

Bernhard Geyer 1. Sep 2005 10:30

Re: Overload und Override für Constructor
 
Definiere deine B,MB,PIN-Attribute als Properties.

Für TComponent-Nachfahren sollte man keine überladenen Konstruktoren definieren, da damit die Verwendung der Komponente in der IDE nicht mehr sinnvoll möglich ist, da hier nur der "default" Konstruktor mit einem Übergabeparameter verwendet wird.

Also verwende Properties und definiert dir ein Active-Property oder eine Connect-Methode.

Flocke 1. Sep 2005 10:31

Re: Overload und Override für Constructor
 
Die erste Version von Create, die du überladen willst, hatte natürlich kein "overload".

Warum nennst du den zweiten Konstruktor nicht einfach anders, z.B. CreateWithParams, dann brauchst du kein Overload.

//EDIT: wo war die rote Box?

meierotto 1. Sep 2005 10:47

Re: Overload und Override für Constructor
 
Danke :thumb: ,

eure Tipps haben mich auf die Lösung gebracht. Natürlich ist nur eines der beiden Creates als override zu definieren, nämlich die dem Parent-Constructor gleiche Prozedur. Den zweiten Constructor habe ich als overload und virtual definiert - und schon klappts.

Bis zur nächsten Frage :zwinker:

tommie-lie 1. Sep 2005 10:53

Re: Overload und Override für Constructor
 
:gruebel: Warum überhaupt override bei Konstruktoren? Die sind doch gar nicht virtuell, macht ja auch keinen Sinn, virtuelle Konstruktoren zu haben :stupid:

Flocke 1. Sep 2005 11:04

Re: Overload und Override für Constructor
 
Zitat:

Zitat von tommie-lie
:gruebel: Warum überhaupt override bei Konstruktoren? Die sind doch gar nicht virtuell, macht ja auch keinen Sinn, virtuelle Konstruktoren zu haben :stupid:

Stimmt auch wieder - gar nicht dran gedacht 8)

Robert Marquardt 1. Sep 2005 11:24

Re: Overload und Override für Constructor
 
Haeh? Ab spaetestens TComponent ist Create virtuell.

BlackJack 1. Sep 2005 11:33

Re: Overload und Override für Constructor
 
oder wenn man von einer eigenen klasse ableitet, die den constructor virtuell gemacht hat.

edit: könnte man beim 2. Create nicht auch statt override; einfach reintroduce; benutzen?

Flocke 1. Sep 2005 11:45

Re: Overload und Override für Constructor
 
Zitat:

Zitat von Robert Marquardt
Haeh? Ab spaetestens TComponent ist Create virtuell.

Auch richtig - heute ist echt nicht mein Tag 8)

Aber nochmal: was soll der ganze Rhabarber? Ein Konstruktor muss nicht Create heißen - gib dem Kind einfach einen anderen Namen, das macht außerdem den Code lesbarer.

Robert_G 1. Sep 2005 11:52

Re: Overload und Override für Constructor
 
Zitat:

Zitat von Flocke
Aber nochmal: was soll der ganze Rhabarber? Ein Konstruktor muss nicht Create heißen - gib dem Kind einfach einen anderen Namen, das macht außerdem den Code lesbarer.

Sorry, aber ich _hasse_ Konstruktoren, die _nicht_ Create heißen.
Delphis *piep* Unsitte, Konstruktoren wie class functions aussehen zu lassen wird damit noch verschlimmert.
Bis jetzt kann man im Code bei einer "class function" namens Create wenigstens noch davon ausgehen, dass sie eigentlich ein Constructor ist. Mit deinem Vorschlag würde das in einem Chaos untergehen.
Warum müssen Konstrutoren/Destruktoren überhaupt einen Namen haben? :wall:

Robert Marquardt 1. Sep 2005 12:15

Re: Overload und Override für Constructor
 
Manchmal braucht man doch einen andersnamigen Konstruktor.
Delphi-Quellcode:
  TJvHidDeviceReadThread = class(TThread)
  private
    ...
    constructor CtlCreate(const Dev: TJvHidDevice);
  public
    ...
    constructor Create(CreateSuspended: Boolean);
  end;
Create wirft immer eine Exception. Nur CtlCreate funktioniert.
TJvHidDeviceReadThread muss in der interface section stehen, aber trotzdem kann ausserhalb der Unit kein Objekt davon erstellt werden.

meierotto 1. Sep 2005 14:04

Re: Overload und Override für Constructor
 
Schön, solch angeregte Diskussion auszulösen :zwinker:
Ich hab mein Problem jedenfalls mit 2 überladenden Konstruktoren gelöst und es funzt.

Danke nochmal :dp:

SirThornberry 1. Sep 2005 14:23

Re: Overload und Override für Constructor
 
Zitat:

Zitat von BlackJack
oder wenn man von einer eigenen klasse ableitet, die den constructor virtuell gemacht hat.

edit: könnte man beim 2. Create nicht auch statt override; einfach reintroduce; benutzen?

NEIN! override ist etwas anderes als reintroduce. Mit override wird der originale Constructor überschrieben und mit reintroduce würde man nur die Warnung unterdrücken das der neue Konstructor den alten verdeckt.

Dax 1. Sep 2005 14:50

Re: Overload und Override für Constructor
 
Zitat:

Zitat von tommie-lie
:gruebel: Warum überhaupt override bei Konstruktoren? Die sind doch gar nicht virtuell, macht ja auch keinen Sinn, virtuelle Konstruktoren zu haben :stupid:

Wieso sollte das keinen Sinn machen?

tommie-lie 1. Sep 2005 15:07

Re: Overload und Override für Constructor
 
Zitat:

Zitat von Dax
Zitat:

Zitat von tommie-lie
:gruebel: Warum überhaupt override bei Konstruktoren? Die sind doch gar nicht virtuell, macht ja auch keinen Sinn, virtuelle Konstruktoren zu haben :stupid:

Wieso sollte das keinen Sinn machen?

Virtuelle Methoden nutzen die RTTI um den tatsächlichen Typ ausfindig zu machen und dessen Methode aufzurufen. Ein sehr gutes Beispiel ist der Destruktor einer Klasse, dessen virtualität essenziell ist. Du kannst eine Variable vom Typ TObject haben und dort beliebige andere Typen drin erzeugen (SomeObject := TBlubb.Create). Rufst du jetzt den Destruktor dieser Variable auf, wird tatsächlich nicht der Destruktor von TObject aufgerufen, sondern der der tatsächlichen Instanz (im Beispiel der von TBlubb). Wäre der Destruktor nicht virtuell, würde der Destruktor von TObject aufgerufen, oder man müsste vorher in den richtigen Typ casten (TBlubb(SomeObject).Free), damit auch der richtige Destruktor aufgerufen wird und alle Ressourcen freigegeben werden.
Bei einem Konstruktor ist so ein Verhalten eigentlich unnötig. Ein Konstruktoraufruf sieht in Pascal üblicherweise so aus:
Delphi-Quellcode:
SomeVar := TSomeType.Create(Params);
Der Datentyp wird also explizit angegeben, es besteht nicht die geringste Frage, welcher Konstruktor aufgerufen werden soll, es muss der von TSomeType sein. Ein Aufruf, bei dem die Laufzeitinformation nötig wäre, wäre SomeVar.Create(Params), der aber keinen Sinn ergibt, da SomeVar entweder noch nicht instanziert war (dann kann es je nach Implementierung des Konstruktor gewaltig knallen, wie wir alle wissen), oder schon ein Objekt besaß, daß aber auch nach dem Aufruf noch in SomeVar bleibt. Es würde alleine der Konstruktor nochmal abgearbeitet werden (mit möglichen Initialisierngsfunktionen. Da ich kein Delphi zur Hand habe, kann ich nicht sagen, ob die üblichen Eigenschaften des Konstruktors auch bei bereits instanzierten Objekten gelten. Falls ja, wird unmittelbar vor dem Aufruf Speicher für eine neue Instanz des Objektes erzeugt und dieser als Rückgabewert zurückgegeben (das ist, was passiert, wenn man SomeVar := TSomeType.Create(Params); aufruft), der aber nirgends wieder referenziert wird. Wieder mangels vorhandenem Delphi bin ich mir nicht sicher, auf welches Objekt self zeigt, wenn man SomeVar.Create aufruft. Zeigt es auf SomeVar (und nicht auf das neu instanzierte Objekt), wäre der u.U. zurückgegebene, nicht referenzierte Speicher auch noch uninitialisiert, selbst wenn ich das Ergebnis also abfangen würde, wäre mein Objekt in einem unerwüsnchten Zustand.
Mir fällt keine Gelegenheit ein, bei der ein virtueller Konstruktor einen praktischen Sinn haben würde, denn von bereits instanzierten Objekten rufe ich keine Konstruktoren auf. Robert meinte, daß ab TComponent der Konstruktor virtual ist, die einzige Erklärung, die ich dafür finde, ist, daß die IDE mit den Komponenten irgendwelche perversen Dinge anstellt, von denen ich lieber nicht wissen möchte, was es ist.

Chewie 1. Sep 2005 15:14

Re: Overload und Override für Constructor
 
@tommie-lie: Was ist mit Metaklassen? Da macht folgendes Konstrukt Sinn:

Delphi-Quellcode:
type
  TBlubb = class;
  TSpinatBlubb  = class(TBlubb);

  TBlubbClass = class of TBlubb;

var
  bc: TBlubbClass;
  b: TBlubb;
begin
  bc := TSpinatBlubb;
  b := bc.Create;
end;
Möglicherweise muss in so einem Fall der Konstruktur virtuell sein. Mit Betonung auf möglicherweise, denn ich hab diese Metaklassen nie eingesetzt.

Flocke 1. Sep 2005 15:15

Re: Overload und Override für Constructor
 
Zitat:

Zitat von tommie-lie
Robert meinte, daß ab TComponent der Konstruktor virtual ist, die einzige Erklärung, die ich dafür finde, ist, daß die IDE mit den Komponenten irgendwelche perversen Dinge anstellt, von denen ich lieber nicht wissen möchte, was es ist.

Der Grund dafür wird darin liegen, wie Delphi aus einer DFM-Datei ein Formular initialisiert. Da alle Elemente auf einem Formular von TComponent abstammen, reicht für die Unterscheidung zwischen z.B. TEdit und TListBox einfach die VMT der Klasse; darüber kann man den (virtuellen) Konstruktor finden.

tommie-lie 1. Sep 2005 15:22

Re: Overload und Override für Constructor
 
Zitat:

Zitat von Chewie
Mit Betonung auf möglicherweise, denn ich hab diese Metaklassen nie eingesetzt.

Ich nur selten und eine solche Notwendigkeit ist mir dabei nicht aufgefallen. Ich habe mir die Metaklassen immer als Typ in Variablengewand vorgestellt. Die "Variable" bc in deinem Beispiel wäre demnach selbst nur ein Typ. Diese Vorstellung hat bisher immer gut mit meinen Beobachtungen übereingestimmt, weswegen ich mir nie die Mühe gemacht habe, des genaue Innenleben auseinanderzunehmen.

@Flocke: Genau soetwas meinte ich mit perversen Dingen ;-)

Robert_G 1. Sep 2005 15:26

Re: Overload und Override für Constructor
 
MetaClasses, und damit virtuelle class methods/properties[1] und Konstruktoren sind doch was feines. ;)
Aber umbenannte Konstruktoren finde ich sogar noch furchtbarer als Benannte im allgemeinen... :?

[1]OK, in Delphi sind properties nicht virtuell...

tigerman33 1. Sep 2005 15:33

Re: Overload und Override für Constructor
 
Wo ist das Problem mit "umbenannten" Konstruktoren? So lange man sich an die Konventionen hält, so dass jeder Konstruktor das Wort "Create" enthält, sollte eigentlich jedem halbwegs durchschnittlich begabten Mitteleuropäer klar sein, dass es sich hierbei um den Konstruktor handelt. Noch dazu, weil man's ja zusätzlich an der Syntax erkennen kann.

BlackJack 1. Sep 2005 16:04

Re: Overload und Override für Constructor
 
Zitat:

Zitat von SirThornberry
NEIN! override ist etwas anderes als reintroduce. Mit override wird der originale Constructor überschrieben und mit reintroduce würde man nur die Warnung unterdrücken das der neue Konstructor den alten verdeckt.

oh, das wusste ich so nicht, da hat mir wohl irgendjemand mal mist erzählt.
also gibt es keine möglichkeit, eine virtuelle procedure zu overriden und deren parameterliste zu ändern (jetzt allgemein auf methoden und nicht nur auf constructoren bezogen)?

Chewie 1. Sep 2005 16:17

Re: Overload und Override für Constructor
 
Zitat:

Zitat von tommie-lie
Ich nur selten und eine solche Notwendigkeit ist mir dabei nicht aufgefallen. Ich habe mir die Metaklassen immer als Typ in Variablengewand vorgestellt. Die "Variable" bc in deinem Beispiel wäre demnach selbst nur ein Typ. Diese Vorstellung hat bisher immer gut mit meinen Beobachtungen übereingestimmt, weswegen ich mir nie die Mühe gemacht habe, des genaue Innenleben auseinanderzunehmen.

Ich auch nicht ;)
Aber ich verwende die gleiche Analogie wie du, und da schauts so aus, dass ich eine Variable eines Basistyps habe, welcher aber eine Referenz auf eine Spezialisierung dieses Basistyps darstellt. Und damit ein Methodenaufruf nun auf den realen Typ und nicht auf den statischen geht, muss diese virtuell sein.
In diesem Kontext ist der Konstruktor eine ganz normale Methode, und damit der Konstruktur der tatsächlichen KLasse und nicht der zur Laufzeit bekannten (TBlubbClass) aufgerufen werden soll, muss dieser virtuell sein. Soweit mein Gedanke.

tommie-lie 1. Sep 2005 16:26

Re: Overload und Override für Constructor
 
Zitat:

Zitat von Chewie
da schauts so aus, dass ich eine Variable eines Basistyps habe, welcher aber eine Referenz auf eine Spezialisierung dieses Basistyps darstellt. Und damit ein Methodenaufruf nun auf den realen Typ und nicht auf den statischen geht, muss diese virtuell sein.

Da ist was dran. Müsste man glatt mal ausprobieren...

Robert_G 1. Sep 2005 16:42

Re: Overload und Override für Constructor
 
Zitat:

Zitat von tommie-lie
Da ist was dran. Müsste man glatt mal ausprobieren...

Ich kann mich da vage an eine ICQ Konversation mit jemanden erinnern, der seine Id3Tags zu .Net bringen wollte.
Gegen Ende kristallierten sich MetaClasses, die sich für gewisse Tags "verantwortlich" fühlen, als nette Möglichkeit heraus.
und wie gates deinen .Net Id3Tags? :zwinker:

tommie-lie 1. Sep 2005 17:03

Re: Overload und Override für Constructor
 
Zitat:

Zitat von Robert_G
Ich kann mich da vage an eine ICQ Konversation mit jemanden erinnern, der seine Id3Tags zu .Net bringen wollte.
Gegen Ende kristallierten sich MetaClasses, die sich für gewisse Tags "verantwortlich" fühlen, als nette Möglichkeit heraus.
und wie gates deinen .Net Id3Tags? :zwinker:

Ich habe dir damals schon gesagt daß ich nicht viel davon weiß ;-)
Außerdem ging es dort ja um Chrome und nicht um Delphi. Ich kann mir gut vorstellen, daß wenn Delphi dort irgendwelche Einschränkungen hat, diese Einschränkungen in Chrome nicht vorhanden sind :zwinker:

Den .NET-Tags geht es augenblicklich schlecht, ich arbeite an was anderem und mir fehlte bisher die Zeit, daran zu arbeiten.

Edit: Außerdem sitze ich augenlicklich lieber an C++, weil es mir einfach noch flexibler scheint als C#1.1 ;-)


Alle Zeitangaben in WEZ +1. Es ist jetzt 08:46 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