![]() |
Leere Klasse von einer anderen abgeleitet
Hallo,
ich habe eine Klasse welche sich von einer anderen ableitet. Beim CONSTRUCTOR-Aufruf der Klasse übergebe ich verschiedene Werte welche in der BASIS-KLasse als Parameter definiert sind und beim debuggen ruft mir Delphi auch den Constructor der Basisklasse auf, ich habe jedoch das Problem, daß ichdauernd eine Exception (Access-voilation schreiben bei Adresse xxxxxxxx nicht möglicch) angezeigt bekomme, wenn ich versuche den Pointer eines Objects an eine Variable des gleichen Typs zu übergeben. Grüße Bigeddie |
Re: Leere Klasse von einer anderen abgeleitet
Es könnte hilfreich sein, wenn du mal den Quellcode postest.
|
Re: Leere Klasse von einer anderen abgeleitet
Dies ist der Code der abgeleiteten Klasse (bis jetzt)
Code:
und dies ist der Code der Basis-Klasse von TWaregroup
type
twaregroup = class(TBWData) public end; implementation { twaregroup }
Code:
Constructor TBWData.create(TheStructure: TBWTable; Path: String);
Var Buffer: TStringList; i: integer; DatLine: TDatLine; Begin FDataStructure := TheStructure; DatStrings := Tlist.Create; der Fehler tritt in der Zeile
Code:
auf und ich weis nicht warumm!!
FDataStructure := TheStructure;
|
Re: Leere Klasse von einer anderen abgeleitet
Zeig uns doch mal die Klassendefinition von TBWData.
Hast du beim Aufruf von twaregroup.create denn auch dein TBWTable initialisiert? |
Re: Leere Klasse von einer anderen abgeleitet
Code:
ist die Deklaration.
TBWData = Class(TObject)
Private FDataStructure: TBWTable; DatStrings: Tlist; FFilter: String; Procedure SetDataStructure(Const Value: TBWTable); Procedure SetFilter(Const Value: String); Published Property DataStructure: TBWTable Read FDataStructure Write SetDataStructure; Property Filter: String Read FFilter Write SetFilter; Function GetLine(Number: word): String; Function Count: Integer; Function GetFieldContent(FieldName: String; LineNumber: Word): String; Function GetFieldContentwhereFieldIncl(InclField: String; InclContent: String; FieldName: String): TStringlist; Overload; Function GetColumn(FieldName: String): TStringList; Function GetLinesWhereFieldContains(FieldName: String; ContString: String): Tlist; Public Function GetFieldContentwhereFieldIncl(InclField: Word; InclContent: String; Fieldnr: word): TStringlist; Overload; Constructor create(TheStructure: TBWTable; FieldList: TList); Overload; Constructor create(TheStructure: TBWTable; Path: String); Overload; TBWTable wird aus einem anderen Objekt bezogen und kann im Parameter TheStructure innerhalb des Constructors eingesehen werden. |
Re: Leere Klasse von einer anderen abgeleitet
Die Instanzen von TBWData arbeiten einwandfrei!
|
Re: Leere Klasse von einer anderen abgeleitet
Und wie sieht dein Constructor aus?
Gruß Daniel |
Re: Leere Klasse von einer anderen abgeleitet
ich rufe den Constructor von TWaregroup so auf wie ich den Constructor von TBWData aufrufe
Code:
beim Aufruf greift Delphi dann auf den COnstructor von TBWData zurück, da in der Klasse Waregroup noch keine Proceduren definiert sind und ich eigentlich auch den Constructor von TBWData verwenden wollte.
myWaregroup : TWaregroup;
.... mywaregroup.create(structur,Pathstring); |
Re: Leere Klasse von einer anderen abgeleitet
Das ist falsch, rufe
Delphi-Quellcode:
auf
mywaregroup := TWareGroup.create(structur,Pathstring)
|
Re: Leere Klasse von einer anderen abgeleitet
Ich weiß ja nicht ob du das in deinem Post einfach unterschlagen hast, aber es fehlt der Aufruf von inherited Create;
|
Re: Leere Klasse von einer anderen abgeleitet
Delphi-Quellcode:
Constructor TBWData.create(TheStructure: TBWTable; Path: String);
Var Buffer: TStringList; i: integer; DatLine: TDatLine; Begin // hier fehlt inherited Create !!!!!! // je nach Konstruktor der Basisklasse müssen ggf. noch Parameter übergeben werden inherited Create; // ************* FDataStructure := TheStructure; DatStrings := Tlist.Create; |
Re: Leere Klasse von einer anderen abgeleitet
Das war ja nicht der COnstructor seiner Klasse, sondern der Klasse von der er abgeleitet hat :)
Und das "inherted" kommt da wahrscheinlich weiter unten. Das Posting von FLocke dürfte aber die Lösung sein... Gruß Daniel |
Re: Leere Klasse von einer anderen abgeleitet
Zitat:
|
Re: Leere Klasse von einer anderen abgeleitet
Zitat:
|
Re: Leere Klasse von einer anderen abgeleitet
Weil IMHO erst nach dem Aufruf von inherited der Speicher für die Instanz (wo also auch die Felder drin gespeichert werden) reserviert wird.
|
Re: Leere Klasse von einer anderen abgeleitet
Zitat:
|
Re: Leere Klasse von einer anderen abgeleitet
Der Konstruktor wird nicht aufgerufen nachdem, sondern um den Speicher zu reservieren.
Zitat:
|
Re: Leere Klasse von einer anderen abgeleitet
Zitat:
Schaut man sich den Assemblercode eines Klassenkonstruktors an, dann sieht es so aus: Jeder Konstruktur hat zwei implizite (unsichtbare) erste Parameter. Der erste ist der Klassendeskriptor (Typ TClass) und der zweite ist ein boolescher Wert der angibt, ob Speicher belegt werden muss. Für den zweiten Parameter gilt: Der äußerste Konstruktur wird mit TRUE aufgerufen und holt sich den Speicher mittels @ClassCreate (eine interne Routine aus der Unit System). Alle inherited Konstruktoren werden mit FALSE aufgerufen, da der Speicher schon belegt ist, und als erster Parameter wird auch nicht mehr der Klassendeskriptor übergeben sondern das jetzt alloziierte Self selbst. Somit haben wir beide halb Recht. (Nachtrag: besser gesagt halb Unrecht 8)) Eine Klasse, die von TObject abgeleitet ist, muss also nicht unbedingt inherited Create aufrufen (obwohl dies saubererer Stil ist). |
Re: Leere Klasse von einer anderen abgeleitet
Hmm, interessant. Aber woher dann die Access Violation? :gruebel:
Ich erinner mich nämlich, dass ich genau den gleichen Fehler schon ab und an hatte--immer dann nämlich, wenn ich im Eifer des Gefechts den Aufruf des inherited Konstruktors vergessen hatte. |
Re: Leere Klasse von einer anderen abgeleitet
Na weil er den Konstruktor direkt aufgerufen hat:
Delphi-Quellcode:
anstelle von
myWaregroup : TWaregroup;
.... mywaregroup.create(structur,Pathstring);
Delphi-Quellcode:
[Nachtrag]
myWaregroup : TWaregroup;
.... mywaregroup := TWaregroup.create(structur,Pathstring); inherited musst du natürlich aufrufen, wenn die Basisklasse eine wirkliche Initialisierung vornimmt. TObject macht das nicht, darum macht es dort keinen Unterschied. Wenn du z.B. von TComponent ableitest, dann ist inherited Create(AOwner); ein absolutes MUSS. |
Re: Leere Klasse von einer anderen abgeleitet
hallo nochmal,
habe jetzt den Constructor in TWaregroup eingefügt
Code:
und in TBWData habe ich ebenfalls den Constructor direkt nach "Begin" um Inherited ergänzt und ich erhalte immernoch den selben FEHLER
TWareGroup.create(TheStructure:TBWTable;Path:String);
begin inherited create(TheStructure,Path)//ruft nach meinem Verständnis den Constructor in TBWData auf end; Übrigens da ich unter Linux am Netz hänge und ich den Code von Hand eintrage bitte ich den Fehler bei meiner letzten Nachricht zu entschuldigen. Grüße Bigeddie |
Re: Leere Klasse von einer anderen abgeleitet
Nachdem Flocke und ich uns jetzt darauf geeinigt haben, beide halb Unrecht zu haben :-D :zwinker:
Daran die Zuweisung beim Constructor-Aufruf noch nachzutragen hast du gedacht, oder? Zitat:
Und dass du den Konstruktor von TBWData nach deinen Angaben so aufrufen kannst wundert mich ehrlich gesagt etwas. |
Re: Leere Klasse von einer anderen abgeleitet
habe jetzt die halbe nach damit verbracht die Variablen in TBWData beim Constructoraufruf von TWaregroup zu überprüfen.
Wwenn ich direkt mit einer Instanz von TBWData arbeite, so ist der Wert von FDatastructure von der Zuweisung des Pointers NIL und enthält nach der Zuweisung den Pointer des übergebenen Objekts. Mache ich das mit einer Instanz von TWaregroup, so ist der Wert von FDataStructure vor der Zuweisung Anzeige in der Watchlist
Code:
kann es vielleicht damit zusammenhängen?
FDatastructur = Nicht verfügbarer Wert
|
Re: Leere Klasse von einer anderen abgeleitet
Vielleicht solltest nochmal den aktuellen Quelltext posten.
|
Re: Leere Klasse von einer anderen abgeleitet
hier nochmal der Deklarationsteil der Klasse TBWData:
Code:
der Deklarationsteil der Klasse TWaregroup
TBWData = Class(TObject)
Private FDataStructure: TBWTable; DatStrings: Tlist; Procedure SetDataStructure(Const Value: TBWTable); Published Property DataStructure: TBWTable Read FDataStructure Write SetDataStructure; // Constructor create(TheStructure: TBWTable; Path: String); Overload; Function GetLine(Number: word): String; Function Count: Integer; Function GetFieldContent(FieldName: String; LineNumber: Word): String; Function GetFieldContentwhereFieldIncl(InclField: String; InclContent: String; FieldName: String): TStringlist; Overload; Function GetColumn(FieldName: String): TStringList; Function GetLinesWhereFieldContains(FieldName: String; ContString: String): Tlist; Public Function GetFieldContentwhereFieldIncl(InclField: Word; InclContent: String; Fieldnr: word): TStringlist; Overload; Constructor create(TheStructure: TBWTable; FieldList: TList); Overload; Constructor create(TheStructure: TBWTable; Path: String); Overload; End;
Code:
und die constructoren:
twaregroup = class(TBWData)
public constructor create(TheStructure: TBWTable; Path: String); end;
Code:
und der Fehler ist immernoch der gleiche
Constructor TBWData.create(TheStructure: TBWTable; Path: String);
Var Buffer: TStringList; i: integer; DatLine: TDatLine; Begin inherited Create; DataStructure := TheStructure; DatStrings := Tlist.Create; Buffer := TStringlist.Create; buffer.LoadFromFile(path + self.FDataStructure.DatFile); If self.FDataStructure.LineIdentifier <> chr(254) Then Begin For i := 0 To buffer.Count - 1 Do Begin If buffer[i][1] = self.FDataStructure.LineIdentifier Then Begin DatLine := TDatline.create(buffer[i], i); DatStrings.Add(DatLine); End; End; End Else Begin For i := 0 To buffer.Count - 1 Do Begin DatLine := TDatline.create(buffer[i], i); DatStrings.Add(DatLine); End; End; End; constructor twaregroup.create(TheStructure: TBWTable; Path: String); begin inherited create(TheStructure,Path); end; |
Re: Leere Klasse von einer anderen abgeleitet
und wie erstellst du die instanz der klasse?
|
Re: Leere Klasse von einer anderen abgeleitet
Code:
und der Aufruf des Constructors
var
myWaregroup : TWareGroup;
Code:
myWaregroup := TWaregroup.create(TheStructure,Pfad);
|
Re: Leere Klasse von einer anderen abgeleitet
Ich weiß nicht, was du in SetDataStructure machst, aber sollte es im Konstruktor nicht so lauten:
Code:
[u][b]F[/b][/u]DataStructure := TheStructure;
|
Re: Leere Klasse von einer anderen abgeleitet
habe ich auch schon probiert, hilfts auch nichts, spart nur einen Aufruf
|
Re: Leere Klasse von einer anderen abgeleitet
Und der Fehler tritt immer noch in eben dieser Zeile auf?
Breakpoint drauf gesetzt? Inhalt von SELF? Inhalt von FDataStructure? Inhalt von TheStructure? |
Re: Leere Klasse von einer anderen abgeleitet
breakpoint auf den constructor-Aufruf
Inhalt der Variablen: TheStructure enthält den Pointer auf ein Objekt von Typ TBWTable und ist in allen stadien des debuggend einsehbar FDataStructure ist innerhalb des Constructors von TBWData nicht einsehbar, sollte jedoch eigentlich vor der Zuweisung NIL sein. habe auch schon probiert über DataStructure (sprich das Property) auf die Variable zuzugreifen |
Re: Leere Klasse von einer anderen abgeleitet
Zitat:
|
Re: Leere Klasse von einer anderen abgeleitet
Ja sicher, die Optimierung habe ich zum debuggen immer ausgeschaltet
|
Re: Leere Klasse von einer anderen abgeleitet
du schreibst ja im constructor
Delphi-Quellcode:
womit du eine setmethode aufrufst. Kann es sein das du in dieser SetMethode auf etwas zugreifst was zu diesem zeitpunkt noch nicht initialisiert ist?
DataStructure := TheStructure;
Vielleicht hilft es ja auch wenn du mal den gesammmten quelltext anhängst damit wir debuggen können. |
Re: Leere Klasse von einer anderen abgeleitet
Procedure TBWData.SetDataStructure(Const Value: TBWTable);
Begin FDataStructure := Value; End; dient also nur der Zuweisung des Pointers an die privte Variable FDataStructure |
Re: Leere Klasse von einer anderen abgeleitet
Das mit dem Codeist ein kleines Problem, denn das Programm greift auf Dateien mit einer größe von ca 1,2GB zu,
die müßte ich auch mitschicken. wie lautet eigentlich der Eintrag der Verzeichnisse fürs debuggen in den projektoptionen, den zeigt mir delphi nicht an? |
Re: Leere Klasse von einer anderen abgeleitet
zum debuggen kann man einerseits den Cursor über bestimmte Variablen halten, oder mit F8/F7 durch/reinsteppen und mit den Watches kann man auch variablen überwachen.
|
Re: Leere Klasse von einer anderen abgeleitet
Liste der Anhänge anzeigen (Anzahl: 1)
Wir können's mal auf die ganz harte Tour versuchen.
1. Breakpoint auf die fehlerhafte Stelle. 2. Programm laufen lassen. 3. Beim erreichen des Breakpoints das CPU-Fenster aufrufen: Ansicht -> Debug-Fenster -> CPU. 4. Dort ein paar Zeilen (~ die Hälfte des sichtbaren Bereichs) zurückgehen. 5. Bildschirm abknipsen inkl. Code und Inhalt der Register (steht rechts). 6. Hier als Anhang posten. Sollte dann so aussehen wie im Anhang. |
Re: Leere Klasse von einer anderen abgeleitet
Liste der Anhänge anzeigen (Anzahl: 1)
hier der Screenshot
|
Re: Leere Klasse von einer anderen abgeleitet
Self ist NIL!
Das bedeutet in 99% der Fälle, dass du irgendwo noch einen Drusel drin hast, so wie wir es schon beschrieben haben - dass du also obj.Create(...) und nicht obj:=Class.Create(...) aufrufst. Vielleicht an einer anderen Stelle als du denkst! |
Alle Zeitangaben in WEZ +1. Es ist jetzt 16:05 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