Autor Beitrag
winx
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 249



BeitragVerfasst: Fr 26.08.05 17:31 
Hallo,

ich habe 2 KLassen
ausblenden volle Höhe Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
type TXMLParser = class

protected
m_XmlToDomParser : TXmlToDomParser;
m_XMLFilePath : String;
m_domImpl : TDomImplementation;
m_domDoc : TdomDocument;
procedure InitDomDoc();

public
property DomDocument : TdomDocument read m_domDoc write m_domDoc;
constructor Create; overload;
constructor Create(filePath:string); overload;
constructor CreateByString(xmlstring:widestring);

destructor destroy();

function startParsing() : boolean;virtual;abstract;

end;

implementation

constructor TXMLParser.Create;
begin
...
end;

constructor TXMLParser.Create(filePath : string);
begin
m_XMLFilePath := filePath;
InitDomDoc();
end;

constructor TXMLParser.CreateByString(xmlstring: widestring);
begin
m_XmlToDomParser := TXmlToDomParser.create(nil);
m_domImpl := TDomImplementation.create(nil);
m_XmlToDomParser.DOMImpl := m_domImpl;
m_domDoc := TdomDocument(m_XmlToDomParser.parseWideString(xmlstring,'','',nil));
end;

procedure TXMLParser.InitDomDoc();
begin

m_XmlToDomParser := TXmlToDomParser.create(nil);
m_domImpl := TDomImplementation.create(nil);
m_XmlToDomParser.DOMImpl := m_domImpl;
try
m_domDoc := m_XmlToDomParser.fileToDom(m_XMLFilePath);
except
MessageDlg(FormLocalizer.textMenu.Items.Caption, mtError, [mbOk], 0);
end;

end;

destructor TXMLParser.destroy;
begin

FreeAndNil(m_XmlToDomParser);
FreeAndNil(m_domImpl);
FreeAndNil(m_domDoc);

end;

end.


und

ausblenden volle Höhe Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
type
TXMLActionListPreParser = class(TXMLParser)
private
m_AllActionsList : TAllActionsList;
m_ParameterList : TLaserParameterList;
public
property AllActionsList : TAllActionsList read m_AllActionsList;

constructor create(filePath:string;paramList:TLaserParameterList);
constructor createByString(xmlString:string;paramList:TLaserParameterList);

destructor destroy();

procedure startPreParsing();

end;

implementation

{ TXMLActionListPreParser }

constructor TXMLActionListPreParser.create(filePath: string;paramList: TLaserParameterList);
begin
inherited create(filePath);
m_AllActionsList := TAllActionsList.Create;
m_ParameterList := paramList;
end;

...

destructor TXMLActionListPreParser.destroy;
begin
inherited;
end;


Wenn ich nun aus einer 3. Klasse heraus eine TXMLPreParser erzeuge und
diesen wieder mit free freigebe, kommt der compiler in keinen der beiden Destruktoren.
ausblenden Delphi-Quelltext
1:
2:
3:
4:
parser := TXMLActionListParser.createByString(xmlstring);
parser.startParsing;
m_ActionGroup := parser.ActionGroup;
FreeAndNil(parser);

Wer kann mir helfen?

Danke

end.

Moderiert von user profile iconAXMD: Code- durch Delphi-Tags ersetzt.
Moderiert von user profile iconChristian S.: Topic aus Sonstiges verschoben am Fr 26.08.2005 um 18:42
AXMD
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 4006
Erhaltene Danke: 7

Windows 10 64 bit
C# (Visual Studio 2019 Express)
BeitragVerfasst: Fr 26.08.05 17:38 
Was in jedem Fall fehlt ist das inherited; im Destroy deiner Klasse im ersten Code (Zeile 57ff).

AXMD
Christian S.
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 20451
Erhaltene Danke: 2264

Win 10
C# (VS 2019)
BeitragVerfasst: Fr 26.08.05 17:42 
Hallo!

Du solltest die Destruktoren jeweils als virtual deklarieren und mittels override überschreiben. Dadurch wird immer der Destruktor der instanzierten und nicht der deklarierten Klasse aufgerufen und durch das inherited dann die nachfolgenden.

Grüße
Christian

_________________
Zwei Worte werden Dir im Leben viele Türen öffnen - "ziehen" und "drücken".
winx Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 249



BeitragVerfasst: Mo 29.08.05 07:54 
Hallo,

es funktioniert nicht!!!!!

Ich hab jetzt nur mal eine Klasse genommen, von dieser ein Objekt erzeugt und will es wieder frei geben
=> er kommt mit FREE nicht in den destruktor...

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
//Die Klasse Parser
constructor create(xmlstring:widestring;name:string);
destructor destroy();override;

//Der Destruktor
destructor TParser.destroy;
begin
  m_name := '';
  inherited;
end;

//Der Aufruf aus einer Funktion

parser := TWsResponseOrderParser.create(response,orderTypeName);
parser.destroy;     //Der Destruktor wird aufgerufen
parser.free         //Der Destruktor wird NICHT aufgerufen
FreeAndNil(parser)  //Der Destruktor wird NICHT aufgerufen

Natürlich rufe ich nur eine der 3 Möglichkeiten auf.

Ich hab echt keine Ahnung mehr, was da falsch laufen kann

Moderiert von user profile iconGausi: Code- durch Delphi-Tags ersetzt.
Udontknow
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 2596

Win7
D2006 WIN32, .NET (C#)
BeitragVerfasst: Mo 29.08.05 08:12 
Hallo!

Du hast aber auch in der Nachfolgeklassen von TXMLParser (hier im Beispiel TWsResponseOrderParser) den Destruktor mit "override" deklariert und in der Implementation jedes Destruktors "inherited"?

Cu,
Udontknow
winx Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 249



BeitragVerfasst: Mo 29.08.05 08:24 
Ich habe den Destruktor in der TXMLParser

mit destructor destroy();virtual;

und in der nachfolgeklasse

mit destructor destroy();override; deklariert

und jedesmal das inherited mit reingenommen, in den destruktor code
Udontknow
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 2596

Win7
D2006 WIN32, .NET (C#)
BeitragVerfasst: Mo 29.08.05 09:11 
Vielleicht zeigst du uns einmal deine Klassenhierarchie, du hast hier jetzt so viele Klassen... Woher kommt plötzlich TParser? Das hiess doch vorher TXMLParser..

Cu,
Udontknow
Christian S.
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 20451
Erhaltene Danke: 2264

Win 10
C# (VS 2019)
BeitragVerfasst: Mo 29.08.05 09:17 
user profile iconwinx hat folgendes geschrieben:
[...] => er kommt mit FREE nicht in den destruktor...
[...]
ausblenden Delphi-Quelltext
1:
2:
3:
4:
parser := TWsResponseOrderParser.create(response,orderTypeName);
parser.destroy;     //Der Destruktor wird aufgerufen
parser.free         //Der Destruktor wird NICHT aufgerufen
FreeAndNil(parser)  //Der Destruktor wird NICHT aufgerufen

Das macht mich irgendwie stutzig, denn "Free" ruft (nach einer Prüfung auf self <> nil) direkt Destroy auf. Wenn also Destroy korrekt durchläuft (und self also nicht nil ist), dann sollte auch Free zum Erfolg führen. Hast Du irgendwo "Free" überschrieben?

Ich gehe natürlich davon aus, dass Du die Befehle oben nicht wirklich alle nacheinander benutzt, sondern jeweils immer nur einen davon :D

_________________
Zwei Worte werden Dir im Leben viele Türen öffnen - "ziehen" und "drücken".
winx Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 249



BeitragVerfasst: Mo 29.08.05 09:47 
habe mir die Sourcen von free auch mal angesehen, aber ich habe die funktion nirgends überschrieben, hab ich zwar mal gemacht, aber dann wieder herausgenommen...
Udontknow
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 2596

Win7
D2006 WIN32, .NET (C#)
BeitragVerfasst: Mo 29.08.05 11:11 
Zitat:
Das macht mich irgendwie stutzig, denn "Free" ruft (nach einer Prüfung auf self <> nil) direkt Destroy auf. Wenn also Destroy korrekt durchläuft (und self also nicht nil ist), dann sollte auch Free zum Erfolg führen. Hast Du irgendwo "Free" überschrieben?


Da sind wir wieder beim Thema Polymorphie! :) Wenn der Destruktor nicht überschrieben ist, sondern ein statischer Destruktor den eigentlichen virtuellen verbirgt, kommt da ein anderes Resultat zustande, dann macht TXMLParser.Free eben nicht dasselbe wie TXMLParser.Destroy.
Free ist statisch, das kann nicht überschrieben werden.

@winx

Nimm doch mal folgendes Grundgerüst, vielleicht erkennst du dann deinen Fehler:

Interface:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
type TParser=class(TObject)
  public
    constructor Create; virtual;
    destructor Destroy; override;
end;

type TXMLParser=class(TParser)
  public
    constructor Create; override;
    destructor Destroy; override;
end;

type TXMLActionListPreParser=class(TXMLParser)
  public
    constructor Create; override;
    destructor Destroy; override;
end;


Implementation:
ausblenden volle Höhe Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
constructor TParser.Create;
begin
  inherited;
  ShowMessage('TParser.Create');
end;

destructor TParser.Destroy;
begin
  ShowMessage('TParser.Destroy');
  inherited;
end;

{ TXMLParser }

constructor TXMLParser.Create;
begin
  inherited;
  ShowMessage('TXMLParser.Create');
end;

destructor TXMLParser.Destroy;
begin
  ShowMessage('TXMLParser.Destroy');
  inherited;
end;

{ TXMLActionListPreParser }

constructor TXMLActionListPreParser.Create;
begin
  inherited;
  ShowMessage('TXMLActionListPreParser.Create');
end;

destructor TXMLActionListPreParser.Destroy;
begin
  ShowMessage('TXMLActionListPreParser.Destroy');
  inherited;
end;


Testaufruf:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
procedure TForm15.Button1Click(Sender: TObject);
var Parser:TObject;
begin
  Parser:=TXMLActionListPreParser.Create;
  Parser.Free;
end;


Du solltest 6 Meldungen erhalten, für das Create und das Destroy je Instanz-Ebene eine Meldung.

Cu,
Udontknow