![]() |
Klassen constructor Aufrufen
ich habe eine Komponente die sich von TImage ableitet.
Wenn ich die Komponente zur Laufzeit in meiner Anwendung erzeuge kann ich einen von beiden class constructoren direkt aufrufen. Es spielt alles wie es soll. Wenn ich die Komponente nun installiere und auf mein Formular ziehe, dann wird der Konstruktor nicht aufgerufen, ich bekomme einen Fehler bei nicht initialisieren lokalen Variablen meiner Klasse. Welcher Constructor wird ausgeführt wenn ich meine Komponente auf ein Form ziehe ?
Delphi-Quellcode:
TPImage = class(TImage)
private { Private-Deklarationen } protected { Protected-Deklarationen } BasicInit: Boolean; public { Public-Deklarationen } constructor create(xpixel, ypixel: Integer); overload; constructor create(aOwner: TWinControl); overload; destructor destroy; override; ... end; |
AW: Klassen constructor Aufrufen
Zitat:
Delphi-Quellcode:
definiert ist. Den musst du überschreiben, wenn das was werden soll.
TComponent
|
AW: Klassen constructor Aufrufen
Rate mal, warum TComponent einen virtuellen Contructor hat. :zwinker:
|
AW: Klassen constructor Aufrufen
mit dem Schlüsselwort override komme ich leider auch nicht weiter
Delphi-Quellcode:
// diesen Ausführen wenn ich K. zur Laufzeit erzeuge
constructor create(xpixel, ypixel: Integer); overload; // diesen Ausführen wenn ich K. auf mein Form gezogen habe constructor create(aOwner: TWinControl); override; overload; Fehlermeldung : [dcc32 Error] Unit_TPl.pas(97): E2037 Declaration of 'Create' differs from previous declaration |
AW: Klassen constructor Aufrufen
das sollte eher so aussehen:
Delphi-Quellcode:
und dann ein inherited create(aowner)....constructor create(aOwner: TWinControl; xpixel, ypixel: Integer); override; reintroduce; |
AW: Klassen constructor Aufrufen
Überschriebene Methoden müssen die gleiche Signatur haben wie die virtuelle in der Basisklasse. D.h.:
Delphi-Quellcode:
constructor Create(AOwner: TComponent); override;
Zitat:
|
AW: Klassen constructor Aufrufen
Dein Interface müsste dann in etwa so aussehen:
Delphi-Quellcode:
Die eigentliche Arbeit steckt aber in den Implementierungen, zu denen wir aber so nicht viel sagen können.
constructor Create(AOwner: TComponent); overload; override;
constructor Create(xpixel, ypixel: Integer); reintroduce; overload; constructor Create(aOwner: TWinControl); reintroduce; overload; // wobei das hier eventuell Probleme bereitet, das TWinControl ja ebenfalls ein TComponent ist. |
AW: Klassen constructor Aufrufen
Zitat:
Delphi-Quellcode:
Aber sowas würde ich nur im alleräußersten Notfall und mit Bauchgrimmen implementieren.
constructor Create(aOwner: TWinControl; NotNeededDummy: integer = 0); reintroduce; overload;
|
AW: Klassen constructor Aufrufen
die Konstruktoren habe ich wie folgt abgeändert :
Delphi-Quellcode:
TPImage = class(TImage) private public { Public-Deklarationen } constructor create(aOwner: TComponent); overload; override; constructor create(aOwner: TComponent; xpixel, ypixel: Integer); reintroduce; overload; .... constructor TPImage.create(aOwner: TComponent); begin inherited create(aOwner); createPParams(nil); end; constructor TPImage.create(aOwner: TComponent ; xpixel, ypixel: Integer); begin // object Defaults inherited create(aOwner); Self.Height := ypixel; Self.Width := xpixel; // user code createPParams(nil); end; Wenn ich die installierte Komponente jetzt auf das Formular ziehe sieht es gut aus ( muss noch mehr testen) allerdings funktioniert das Erzeugen zur Laufzeit jetzt nicht mehr also
Delphi-Quellcode:
// Größe des Bilder möchte ich via align einstellen
FPI := TPImage.create(Panel1); // ich gebe die Größe des Bildes vor ... FPI := TPImage.create(Panel1,300,300); dann wird auf meinem Panel nichts mehr anzeigt , ich muss dann nochmals FPI.Parent := Panel1; einfügen. Ich dachte die Info bekommt die Class schom beim Ausführen des KOnstruktors |
AW: Klassen constructor Aufrufen
Zitat:
Es könnte ja
Delphi-Quellcode:
sein...
AInstance := TFoo.Create(Form1,10,10);
AInstance.Parent := Panel1; |
AW: Klassen constructor Aufrufen
Komponenten im FormDesigner bekommen als Owner immer die Form und als Parent das, worauf sie liegen.
Aber du kannst im Constructor ja dennoch Parent = Owner setzen, für denn Fall, dass die Komponente manuell erstellt wird. (lässt sich ja nach dem Constructor neu zuweisen, wenn es doch ein anderer Parent werden soll) Man kann über Self.ComponentState (im Constructor siehe Owner.ComponentState) rausbekommen, ob die Komponente grade im FormDesigner liegt, oder ob soe grade aus einer DFM geladen wird. Nur der TForm-Constructor ist ein Sonderfall, wenn dieser über Application.CreateForm erstellt wird, denn da ist der Zustannd bereits im Constructor bekannt. Leider waren Her Wirth und Borland nicht nett genug, das auch im TReader (DFM-Loader) zu machen. |
AW: Klassen constructor Aufrufen
Zitat:
Wenn ich eine Object erzeuge das ich von einem anderen Object ableite schreibe ich i.d.R. nicht override... Beispiel:
Delphi-Quellcode:
Denn mit einem TMyButton.Create wird mein constructor aufgerufen hier mache ich den inherited
type
TMyButton = class(TButton) public Constructor Create(AOwner : TComponent); end; Warum also ein override? Weil nicht mein Constructor aufgerufen wird? Anders bei Methoden. ![]() |
AW: Klassen constructor Aufrufen
Zitat:
Der Sinn von virtuellen Konstruktoren ist ja genau der, daß sie auch aufgerufen werden können, wenn dem Aufrufenden die tatsächliche Klasse nicht bekannt ist. |
AW: Klassen constructor Aufrufen
Zitat:
|
AW: Klassen constructor Aufrufen
Zitat:
Zitat:
:thumb: Immer wenn das Telefon klingelt, sollte ich meine Post vor dem senden erst nochmal lesen... |
AW: Klassen constructor Aufrufen
Zitat:
Delphi-Quellcode:
sparen!
// user code
createPParams(nil); Also:
Delphi-Quellcode:
constructor TPImage.create(aOwner: TComponent);
begin inherited create(aOwner); createPParams(nil); end; constructor TPImage.create(aOwner: TComponent ; xpixel, ypixel: Integer); begin // object Defaults inherited create(aOwner); Self.Height := ypixel; Self.Width := xpixel; end; |
AW: Klassen constructor Aufrufen
Zitat:
Der Owner verwaltet die Instanz des Controls und gibt sie frei wenn er selbst freigegeben wird. Das Parent ist das Control auf dem das erstellte Control platziert werden soll. |
AW: Klassen constructor Aufrufen
Zitat:
|
AW: Klassen constructor Aufrufen
Hmm..
Wäre es dann nicht besser, das inherited weg zu lassen? Dann würden beide Aufrufe zur selben 'Basis' passen, ohne immer alles aus dem Einen im Anderen wieder nachziehen zu müssen. |
AW: Klassen constructor Aufrufen
[edit] Jupp, weg damit.
Zitat:
also:
Delphi-Quellcode:
constructor TPImage.Create(aOwner: TComponent);
begin inherited; //inherited Create(aOwner); // wenn es gleich ist (Name und Parameter, dann muß man es nicht angeben) ... finde ich übersichtlicher, da man so weiß, dass nur der direkte Vorfahre gemeint ist createPParams(nil); end; constructor TPImage.Create(aOwner: TComponent; xpixel, ypixel: Integer); begin // object Defaults Create(aOwner); // inherited Create(aOwner); // hier ohne Inherited, wenn man den "Eigenen" meint Self.Height := ypixel; Self.Width := xpixel; end; |
Alle Zeitangaben in WEZ +1. Es ist jetzt 07:28 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz