![]() |
Pointer-Eigenschaft einer Klasse: Zugriffsverletzung
Hallo,
angenommen ich haben 2 Klassen, die im Interface-Teil einer Unit direkt untereinander stehen:
Delphi-Quellcode:
Im weiteren Verlauf erzeuge ich jeweils ein Objekt (Vater zuerst), mit Create und belege die Werte. Dabei kommt an einer Stelle eine Fehlermeldung:
Type TFather = Class
vorname: string; alter: integer; end; Type TChild = Class vorname: string; alter: integer; Vater: Pointer; // <- hier kommt das Problem; hier soll der Papa rein. end;
Delphi-Quellcode:
Und zwar kommt an der gekennzeichneten Stelle eine Speicher-Zugriffsverletzung.
VaterObject:= TFather.Create;
VaterObject.vornamename:= 'Horst'; VaterObject.alter:= 30; ChildObject= TChild.Create; VaterObject.vornamename:= 'Horstsohn'; VaterObject.alter:= 3; ChildObject.Vater:= VaterObject; // <- Hier kommt die Fehlermeldung die ich nicht verstehe! Um folgendes Zitat vorweg zu nehmen: Zitat:
Delphi-Quellcode:
dereferenzieren.
TClassname(Child.Vater).blabla
Wo es super funktioniert, ist beim TTreeItem. Hier gibt es die Eigenschaft Data:Pointer. Funktioniert einfandfrei:
Delphi-Quellcode:
Weiß jemand was ich hier falsch mache?
tvitem.data:= xy;//beliebige Objektstruktur
Grüße! |
Re: Pointer-Eigenschaft einer Klasse: Zugriffsverletzung
Delphi-Quellcode:
Du willst ja schliesslich die Adresse des Objektes in den Pointer stecken.
Child.Vater := @VaterObjekt;
|
Re: Pointer-Eigenschaft einer Klasse: Zugriffsverletzung
Funktioniert auch nicht (gleiche Fehlermeldung).
Danke trotzdem |
Re: Pointer-Eigenschaft einer Klasse: Zugriffsverletzung
Was funktioniert ist:
Delphi-Quellcode:
Hier kommt dann wierder der Fehler:
var tmp_ptr: Pointer;
... tmp_ptr:= @VaterObject;
Delphi-Quellcode:
Kann es sein dass die Klasseneigenschaft irgendwie geschützt ist?
ChildObject.Vater:= tmp_ptr;
Sollte ich sie vielleicht als Public deklarieren? Oder gibt es irgendwelche Sperren bzw. Restriktionen, bei denen nicht mehrere Objekte in unterschiedllichen Klassen sich gegenseitig aufrufen dürfen? |
Re: Pointer-Eigenschaft einer Klasse: Zugriffsverletzung
Bei D6 muss man bei Pointern IHMO noch etwas typecasten.
Versuch doch mal diese Sachen:
Delphi-Quellcode:
ChildObject.Vater:= pointer(VaterObject);
//bzw. ChildObject.Vater:= pointer(@VaterObject); //wobei das eigentlich egal sein sollte |
Re: Pointer-Eigenschaft einer Klasse: Zugriffsverletzung
Zitat:
Delphi-Quellcode:
TChild = Class
vorname: string; alter: integer; FVater: Pointer; public property Vater: Pointer read FVater write FVater; // <-- fehlt end; |
Re: Pointer-Eigenschaft einer Klasse: Zugriffsverletzung
Eigentlich müsste es genauso funktionieren, wie du es gemacht hast - cih verwende in einem Projekt genau die gleiche Struktur und das klappt wunderbar (das mit dem @ kannst du imho auch vergessen, da Objekte eh nur als Pointer zugewiesen werden).
Daher die Frage: Hast du das Beispiel auch genau in der einfachen Form, wie du sie hier reingestellt hast, mal ausprobiert? Ich würde ja eher vermuten, dass der Fehler woanders liegt, da gerade beim Zuweisen einer Speicheradresse an einen Pointer nix passieren sollte. Ist das, was hier vom Typ TChild ist, richtig deklariert? Rufst du vom richtigen Objekt den constructor auf? Würde vermuten, dass eher in dem Bereich ein Fehler liegt, denn offenbar kann auf die Eigenschaft "fahther" nicht zugegriffen werden. Das könnte vielleicht so passieren:
Delphi-Quellcode:
Mal so als Idee. Allerdings gerade ungetestet.
procedure irgendwas;
var vadder: TFahther; kind: TChild; begin vadder:=TFahther.Create; // irgendwelche Werte an den Vater... kind:=TChild(Tfahther.Create); // machst du in deinem komplexeren Projekt irgendwie sowas? kind.vater:=vadder; // ...denn in dem Fall müsste genau dein Fehler kommen. end; Bis denn Bommel |
Re: Pointer-Eigenschaft einer Klasse: Zugriffsverletzung
Dein Minmalbeispiel lässt sich bei mir anstandslos kompilieren (nach Änderung der Eigenschaft 'vornamename'...) und läuft auch ohne Fehlermeldung durch. Das Problem liegt also wahrscheinlich an etwas anderem.
|
Re: Pointer-Eigenschaft einer Klasse: Zugriffsverletzung
Zitat:
ansonsten, das mit der fehlenden Property klingt logisch, ich werd es ausprobieren. Ich prüfe mal nochmal ob der Fehler nicht vielleicht doch woanders liegt. Bis hierher Danke an alle, aber lasst mal "kurz" locker... will nicht dass sich noch mehr andere den Kopf zerbrechen und dabei Äpfel mit Birnen vergleichenm, weil der Fehler bei mir liegt... |
Re: Pointer-Eigenschaft einer Klasse: Zugriffsverletzung
Zitat:
Das merkst du in meinem Beispiel aber erst zur Laufzeit, weil du das Kind ja als TChild deklariert hast: Editor und Compiler werden sich also nicht über die fehlende Eigenschaft "vater" beschweren. Und wegen des Typecasts lassen sie dir auch durchgehen, dass du den falschen Constructor aufrufst. Hm, hoffe, ich hab das 1. richtig und 2. verständlich erklärt. :) Bis denn Bommel |
Re: Pointer-Eigenschaft einer Klasse: Zugriffsverletzung
@Bommel
Ich bitte vielmals um Entschuldigung. Ich habe mich verguckt. Ich mache es so...
Delphi-Quellcode:
Womit wir wieder bei 0 anfangen.
procedure irgendwas;
var vadder: TFahther; kind: TChild; begin vadder:=TFahther.Create; // irgendwelche Werte an den Vater... kind:=TChild(Create); // <- also ich rufe NICHT den Vater-Consrtruktor auf. Diesen Aspekt hatte ich nicht bemerkt vorhin... kind.vater:=vadder; end; Sorry dass Du das jetzt für die Katz erklärt hast... |
Re: Pointer-Eigenschaft einer Klasse: Zugriffsverletzung
Ähmm...
Meinst du
Delphi-Quellcode:
oder
kind:=TChild(Create);
Delphi-Quellcode:
Ersteres wäre ja nett, weiß gerade nicht, was das eigentlich machen würde. ;)
kind:=TChild.Create;
Könnte aber der Fehler sein, falls du es wirklich so machst... Ansonsten gehen mir auch die Ideen aus. Bis denn Bommel |
Re: Pointer-Eigenschaft einer Klasse: Zugriffsverletzung
1. @Object ist was anderes als Pointer(Object)!! Das erste ist die Adresse wo die Instanzenadresse liegt, das zweite ist die Instanzenadresse als Pointer. Letzteres ist das gesuchte, wenn du wirklich Pointer verwenden willst.
2. Wenn du nur Objekte in dieser Eigenschaft ablegen willst, dann nutze TObject als Typ. Damit kannst du auch zur Laufzeit abfragen, was denn nun hinterlegt ist für ein Objekt (IS Operator). 3. Wenn es sich nur um Vater und Kind handelt, dann könntest du im Kind direkt die Eigenschaft von TVater deklarieren (Voraussetzung: das zweite "type" Statement entfernen). Da du aber meintest, dass es unterschiedliche Typen geben kann für die Eigenschaft, dann müssten diese alle von TVater abgeleitet sein. |
Re: Pointer-Eigenschaft einer Klasse: Zugriffsverletzung
Auch hier wieder verguckt.
Natürlich ".Create". Ok, ich mach schon einige Zeit mit Klassen rum und habe da ziemlich Routine, weshalb ich sowas dann nicht sehe. Nur das mit den Zeigern DACHTE ich verstanden zu haben, aber dem ist scheinbar doch nicht so. Habe inzwischen alles probiert: TypeCast, Properties etc.... Ohne Erfolg. |
Re: Pointer-Eigenschaft einer Klasse: Zugriffsverletzung
@Muetze1
Danke für den Tipp, werde es sofort versuchen. |
Re: Pointer-Eigenschaft einer Klasse: Zugriffsverletzung
Zitat:
Das Problem lässt sich einfach mit einer Vorwärtsdeklaration lösen:
Delphi-Quellcode:
In würde übrigens von TPersistent ableiten, damit man die Objekte auch kopieren kann.
Type
TFather = class; // Vorwärtsdeklaration. Delphi weiss jetzt, es gibt die Klasse TChild = Class vorname: string; alter: integer; Vater: TFather; // ganz einfach so end; TFather = Class vorname: string; alter: integer; end; |
Re: Pointer-Eigenschaft einer Klasse: Zugriffsverletzung
Wozu eine Forward Deklaration, wenn er im Vater nicht das Kind referenziert? Somit einfach den Vater vor dem Kind deklarieren. (siehe mein Beitrag zuvor, Punkt 3)
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 12:40 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