Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Leere Klasse von einer anderen abgeleitet (https://www.delphipraxis.net/52529-leere-klasse-von-einer-anderen-abgeleitet.html)

Bigeddie 30. Aug 2005 13:53


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

DevilsCamp 30. Aug 2005 13:54

Re: Leere Klasse von einer anderen abgeleitet
 
Es könnte hilfreich sein, wenn du mal den Quellcode postest.

Bigeddie 30. Aug 2005 14:06

Re: Leere Klasse von einer anderen abgeleitet
 
Dies ist der Code der abgeleiteten Klasse (bis jetzt)
Code:
type
  twaregroup = class(TBWData)
  public

  end;
implementation

{ twaregroup }
und dies ist der Code der Basis-Klasse von 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:
FDataStructure := TheStructure;
auf und ich weis nicht warumm!!

Jelly 30. Aug 2005 14:16

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?

Bigeddie 30. Aug 2005 14:23

Re: Leere Klasse von einer anderen abgeleitet
 
Code:
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;
ist die Deklaration.

TBWTable wird aus einem anderen Objekt bezogen und kann im Parameter TheStructure innerhalb des Constructors eingesehen werden.

Bigeddie 30. Aug 2005 14:37

Re: Leere Klasse von einer anderen abgeleitet
 
Die Instanzen von TBWData arbeiten einwandfrei!

dfried 30. Aug 2005 14:37

Re: Leere Klasse von einer anderen abgeleitet
 
Und wie sieht dein Constructor aus?

Gruß
Daniel

Bigeddie 30. Aug 2005 14:44

Re: Leere Klasse von einer anderen abgeleitet
 
ich rufe den Constructor von TWaregroup so auf wie ich den Constructor von TBWData aufrufe
Code:
myWaregroup : TWaregroup;
....
mywaregroup.create(structur,Pathstring);
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.

Flocke 30. Aug 2005 15:04

Re: Leere Klasse von einer anderen abgeleitet
 
Das ist falsch, rufe
Delphi-Quellcode:
mywaregroup := TWareGroup.create(structur,Pathstring)
auf

tigerman33 30. Aug 2005 15:07

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;

shmia 30. Aug 2005 15:10

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;

dfried 30. Aug 2005 15:13

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

tigerman33 30. Aug 2005 15:15

Re: Leere Klasse von einer anderen abgeleitet
 
Zitat:

Zitat von dfried
Und das "inherted" kommt da wahrscheinlich weiter unten.

Dann versuchst du in nicht initialisierten Speicher zu schreiben. Und das gibt nunmal eine Access Violation

Flocke 30. Aug 2005 15:24

Re: Leere Klasse von einer anderen abgeleitet
 
Zitat:

Zitat von tigerman33
Dann versuchst du in nicht initialisierten Speicher zu schreiben. Und das gibt nunmal eine Access Violation

:gruebel: Wieso sollte der Speicher nicht initialisiert sein?

tigerman33 30. Aug 2005 15:25

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.

Flocke 30. Aug 2005 15:26

Re: Leere Klasse von einer anderen abgeleitet
 
Zitat:

Zitat von tigerman33
Weil IMHO erst nach dem Aufruf von inherited der Speicher für die Instanz (wo also auch die Felder drin gespeichert werden) reserviert wird.

Nö, der Konstruktur wird erst aufgerufen NACHDEM der Speicher reserviert wurde, sonst wär SELF ja NIL.

tigerman33 30. Aug 2005 15:30

Re: Leere Klasse von einer anderen abgeleitet
 
Der Konstruktor wird nicht aufgerufen nachdem, sondern um den Speicher zu reservieren.
Zitat:

Sonst wär self ja nil
Nicht notwendigerweise. Nach dem Aufruf von Destroy ist es ja schließlich auch nicht nil.

Flocke 30. Aug 2005 15:49

Re: Leere Klasse von einer anderen abgeleitet
 
Zitat:

Zitat von tigerman33
Der Konstruktor wird nicht aufgerufen nachdem, sondern um den Speicher zu reservieren.

Eigentlich wird der Konstruktor aufgerufen, um den Speicher zu initialisieren.

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).

tigerman33 30. Aug 2005 21:31

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.

Flocke 30. Aug 2005 21:34

Re: Leere Klasse von einer anderen abgeleitet
 
Na weil er den Konstruktor direkt aufgerufen hat:
Delphi-Quellcode:
myWaregroup : TWaregroup;
....
mywaregroup.create(structur,Pathstring);
anstelle von
Delphi-Quellcode:
myWaregroup : TWaregroup;
....
mywaregroup := TWaregroup.create(structur,Pathstring);
[Nachtrag]

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.

Bigeddie 30. Aug 2005 23:35

Re: Leere Klasse von einer anderen abgeleitet
 
hallo nochmal,

habe jetzt den Constructor in TWaregroup eingefügt
Code:
TWareGroup.create(TheStructure:TBWTable;Path:String);
begin
inherited create(TheStructure,Path)//ruft nach meinem Verständnis den Constructor in TBWData auf
end;
und in TBWData habe ich ebenfalls den Constructor direkt nach "Begin" um Inherited ergänzt und ich erhalte immernoch den selben FEHLER

Ü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

tigerman33 31. Aug 2005 08:23

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:

Delphi-Quellcode:
myWaregroup : TWaregroup;
....
mywaregroup.create(structur,Pathstring);
anstelle von
Delphi-Quellcode:
myWaregroup : TWaregroup;
....
mywaregroup := TWaregroup.create(structur,Pathstring);

(@Flocke: Da hast du übrigens vollkommen, zu 100% Recht! :???: :thumb: )

Und dass du den Konstruktor von TBWData nach deinen Angaben so aufrufen kannst wundert mich ehrlich gesagt etwas.

Bigeddie 31. Aug 2005 08:49

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:
FDatastructur = Nicht verfügbarer Wert
kann es vielleicht damit zusammenhängen?

tigerman33 31. Aug 2005 09:05

Re: Leere Klasse von einer anderen abgeleitet
 
Vielleicht solltest nochmal den aktuellen Quelltext posten.

Bigeddie 31. Aug 2005 09:31

Re: Leere Klasse von einer anderen abgeleitet
 
hier nochmal der Deklarationsteil der Klasse TBWData:
Code:
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;
der Deklarationsteil der Klasse TWaregroup
Code:
twaregroup = class(TBWData)
  public
    constructor create(TheStructure: TBWTable; Path: String);
  end;
und die constructoren:
Code:
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;
und der Fehler ist immernoch der gleiche

SirThornberry 31. Aug 2005 09:33

Re: Leere Klasse von einer anderen abgeleitet
 
und wie erstellst du die instanz der klasse?

Bigeddie 31. Aug 2005 09:40

Re: Leere Klasse von einer anderen abgeleitet
 
Code:
var
  myWaregroup : TWareGroup;
und der Aufruf des Constructors

Code:
myWaregroup := TWaregroup.create(TheStructure,Pfad);

Flocke 31. Aug 2005 09:47

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;

Bigeddie 31. Aug 2005 09:52

Re: Leere Klasse von einer anderen abgeleitet
 
habe ich auch schon probiert, hilfts auch nichts, spart nur einen Aufruf

Flocke 31. Aug 2005 09:59

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?

Bigeddie 31. Aug 2005 10:13

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

DevilsCamp 31. Aug 2005 10:20

Re: Leere Klasse von einer anderen abgeleitet
 
Zitat:

Zitat von Bigeddie
FDataStructure ist innerhalb des Constructors von TBWData nicht einsehbar, sollte jedoch eigentlich vor der Zuweisung NIL sein.

Auch dann nicht, wenn du in den Projekt-Eigenschaften die Optimierung ausschaltest?

Bigeddie 31. Aug 2005 10:24

Re: Leere Klasse von einer anderen abgeleitet
 
Ja sicher, die Optimierung habe ich zum debuggen immer ausgeschaltet

SirThornberry 31. Aug 2005 10:24

Re: Leere Klasse von einer anderen abgeleitet
 
du schreibst ja im constructor
Delphi-Quellcode:
DataStructure := TheStructure;
womit du eine setmethode aufrufst. Kann es sein das du in dieser SetMethode auf etwas zugreifst was zu diesem zeitpunkt noch nicht initialisiert ist?

Vielleicht hilft es ja auch wenn du mal den gesammmten quelltext anhängst damit wir debuggen können.

Bigeddie 31. Aug 2005 10:27

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

Bigeddie 31. Aug 2005 11:08

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?

SirThornberry 31. Aug 2005 11:32

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.

Flocke 31. Aug 2005 12:15

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.

Bigeddie 31. Aug 2005 12:43

Re: Leere Klasse von einer anderen abgeleitet
 
Liste der Anhänge anzeigen (Anzahl: 1)
hier der Screenshot

Flocke 31. Aug 2005 13:05

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.
Seite 1 von 2  1 2      

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