![]() |
Klassen und Pointer - Fehlerursache?
Hallo, ich hab wieder mal ein Problem :(
Erstmal folgender Beispielcode:
Delphi-Quellcode:
Der Sinn ist, dass ich drei Klassen habe (A, B und C). Form1 erstellt ein Objekt von Klasse A. Und dieses erstellt ein Objekt von Klasse B und C. - Nun ruft Objekt C über sein Elternobjekt (Objekt A) die Funktion des Objekts B auf. Das Init() dient nur dazu, dem Objekt, den Pointer seines übergeordneten Objektes zu geben.
type
TKlasseB = class public vOwner: Pointer; vText: String; function Init( Owner: Pointer ): Boolean; function Test( Text: String ): Boolean; end; type TKlasseC = class public vOwner: Pointer; function Init( Owner: Pointer ): Boolean; function Test( Text: String ): Boolean; end; type TKlasseA = class public vOwner: Pointer; KlasseB: TKlasseB; KlasseC: TKlasseC; function Init( Owner: Pointer ): Boolean; end; type TForm1 = class(TForm) Button1: TButton; Button2: TButton; procedure Button1Click(Sender: TObject); procedure Button2Click(Sender: TObject); private { Private declarations } public { Public declarations } KlasseA: TKlasseA; end; var Form1: TForm1; implementation {$R *.dfm} function TKlasseA.Init( Owner: Pointer ): Boolean; begin vOwner := Owner; KlasseB := TKlasseB.Create; KlasseC := TKlasseC.Create; KlasseB.Init( @self ); KlasseC.Init( @self ); Result := True; end; function TKlasseB.Init( Owner: Pointer ): Boolean; begin vOwner := Owner; Result := True; end; function TKlasseB.Test( Text: String ): Boolean; begin vText := Text; Result := True; end; function TKlasseC.Init( Owner: Pointer ): Boolean; begin vOwner := Owner; Result := True; end; function TKlasseC.Test( Text: String ): Boolean; begin TKlasseA( vOwner^ ).KlasseB.vText := Text; Result := True; end; procedure TForm1.Button1Click(Sender: TObject); begin KlasseA := TKlasseA.Create; KlasseA.Init( @self ); end; procedure TForm1.Button2Click(Sender: TObject); begin KlasseA.KlasseC.Test('Hallo'); end; end. Das Problem: Ich krieg beim Klick auf Button2 einen Fehler (Access Violation). Scheinbar kann die Variable vText nicht beschrieben werden. Woran liegt das? Hab ich was mit den Pointer falsch gemacht? Ich hab folgendes noch getestet gehabt:
Delphi-Quellcode:
Und scheinbar sind die Pointer nicht gleich. Aber 'self' ist das Objekt von dem die Funktion gerade gestartet ist und @self ist dann die Adresse auf dieses Objekt. Naja, und @Form1.KlassA müsste ja dann das selbe sein. Oder lassen sich Pointer gar nicht vergleichen? Und irgendwie hab ich das Gefühl ich greif beim Ändern der Variable, auf ein anderes (offensichtlich nicht erstelltes) Objekt der Klasse zu. Aber eigentlich müsste es ja das selbe sein. Ich bin verwirrt :(
function TKlasseA.Init(): Boolean;
begin If @self = @Form1.KlasseA Then ShowMessage('Ja'); end; Hoffe mir kann jemand helfen. Danke schonmal. |
Re: Klassen und Pointer - Fehlerursache?
Alle Instanzenvariablen (somit auch Self) sind intern Zeiger auf das eigentliche Objekt.
Daraus ergeben sich folgende Dinge: @Self erstellt eine temporärer Zeiger, also eine temporäre Variable, welcher die Adresse von Self aufnimmt. Da Self nur ein weiterer Zeiger ist, erstellst du einen Zeiger auf einen Zeiger auf das Objekt. Der zweite Zeiger in dieser Kette ist eine temporäre Variable, welche ihre Gültigkeit und somit ihren Speicherplatz mit dem Ende der Procedure verliert, in der dieser Code steht. Somit: Dein Zeiger den du Init übergibst, ist nach Ausführung der aufrufenden Funktion hinfällig und zeigt auf diesen temporären Speicher, der nicht mehr zugeordnet ist und schon fleissig für andere Dinge genutzt wird. Nochwas: Alle Objekte sind von TObject abgeleitet. Die Angabe von class(TObject) ist optional und entspricht damit class Somit: Entferne überall Pointer und ersetze mit TObject. Zusätzlich entferne überall den impliziten Adressoperator @ und es sollte so funktionieren wie du es dir gedacht hast. |
Re: Klassen und Pointer - Fehlerursache?
Dass self schon ein Pointer ist, hab ich übersehen. Klingt aber logisch :)
Danke vielmals für die ausführlichen Erklärungen. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 23:14 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