Autor Beitrag
anton
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 16

XP, Linux
D5 Standard
BeitragVerfasst: Mo 12.07.04 18:46 
Hallo. Ich habe auf ein Problem gestoßen, das ich selbst nicht lösen konnte, und die Suche nach einer Lösung im Internet hat auch nichts ergeben. Also probiere ich es hier. Ich habe eine Klasse geschrieben deren Objekte Objekte anderer Klassen beinhalten. Die Methoden Create und Free habe ich überschrieben, so dass beim Anlegen oder beim Löschen des Behälterobjekts auch seine Unterobjekte angelegt bzw. gelöscht werden. Wenn ich jetzt aber ein Behälterobjekt anlege, kommt es beim Zugriff auf die Daten der Unterobjekte zu einem Laufzeitfehler. Ich habe das Programm und die Klassen auf das Minimum reduziert, damit das Problem besser verständlich ist. s. Code:

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:
67:
68:
69:
70:
71:
72:
73:
74:
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type

  TInt=class
    x:integer;
    constructor create;
  end;

  TContainer=class
    f:array[1..10of TInt;
    constructor create;
    destructor free;
  end;

  TForm1 = class(TForm)
    Button1: TButton;
    Button2: TButton;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;

var
  Form1: TForm1;
  c:TContainer;

implementation

{$R *.dfm}


constructor TInt.create;
begin
  inherited create;
  x:=1;
end;

constructor TContainer.create;
var i:integer;
begin
  for i:=1 to 10 do
    f[i].create;
end;

destructor TContainer.free;
var i:integer;
begin
  for i:=1 to 10 do
    f[i].free;
  inherited free;
end;

procedure TForm1.Button1Click(Sender: TObject);

begin
  c:=TContainer.create;
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
  c.free;
end;

end.


Es ist ein Standardformular mit zwei Buttons. 1. Button=>Objekt wird erschaffen, 2. Button=>Objekt wird gelöscht. Behälterklasse heißt TContainer und die Unterklasse heißt TInt. Kann mir vielleicht jemand sagen, was ich falsch mache?


Moderiert von user profile iconPeter Lustig: Code- durch Delphi-Tags ersetzt.
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 12.07.04 18:58 
Hallo!

Auch die TInts müssen über "f[i] := TInt.Create" erstellt werden, wie Du es beim Container schon ganz richtig gemacht hast!

MfG
Peter

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

XP, Linux
D5 Standard
BeitragVerfasst: Mo 12.07.04 19:48 
Oh Mann, ich habe mich einfach verschrieben. Ich sollte f[i]:=TInt.create anstatt f[i].create schreiben. Ich habe 4 Stunden dran gesessen und alles Mögliche ausprobiert. Jetzt läuft mein Programm. Vielen Dank für die Antwort.
Muetze1
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 346



BeitragVerfasst: Di 13.07.04 19:28 
Moin!

Nochwas: Den Destructor hast du nicht überschrieben sondern einen neuen definiert und die Methode Free versteckt. Das sollte dir aber auch der Compiler melden als Warning oder Hint. Für den Destructor folgendes verwenden:

ausblenden Delphi-Quelltext
1:
  Destructor Destroy; Override;					


Du kannst weiterhin Free aufrufen, weil die Methode ruft einfach nur Destroy nach einer kurzen Prüfung auf.

MfG
Muetze1
anton Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 16

XP, Linux
D5 Standard
BeitragVerfasst: Di 13.07.04 20:24 
Das habe ich ehrlich gesagt nicht verstanden. Ich rufe doch in der free-Methode die übergeordnete free-Methode auf. Mit create habe ich das doch genauso getan. Oder stehe ich irgendwie auf dem Schlauch?

[edit]
Ach Sorry, jetzt sehe ich das. In der TInt-Klasse habe ich die Deklaration der Free-Methode vergessen. Aber in meinem richtigen Programm ist sie drin :-) Danke für den Hinweis.
Muetze1
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 346



BeitragVerfasst: Di 13.07.04 21:49 
Moin!

anton hat folgendes geschrieben:
Das habe ich ehrlich gesagt nicht verstanden. Ich rufe doch in der free-Methode die übergeordnete free-Methode auf. Mit create habe ich das doch genauso getan. Oder stehe ich irgendwie auf dem Schlauch?

[edit]
Ach Sorry, jetzt sehe ich das. In der TInt-Klasse habe ich die Deklaration der Free-Methode vergessen. Aber in meinem richtigen Programm ist sie drin :-) Danke für den Hinweis.


Nein, immer noch nicht. Free ist eine Methode und kein Destructor. Der Destructor heisst Destroy und sollte überschrieben werden (ist schon virtuell definiert in TObject).

MfG
Muetze1
anton Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 16

XP, Linux
D5 Standard
BeitragVerfasst: Do 15.07.04 12:39 
Ok, ich habe immer gedacht, dass free ein Destruktor ist, aber du hast Recht. Das war ein Fehler. Aber was wird, wenn ich anstatt von "destructor free" "procedure free" schreibe. Dann ruft die Methode die übergeordnete Methode "Free" auf und die ruft destroy auf. das wäre dann doch richtig, oder?
maximus
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 896

Win XP, Suse 8.1
Delphi 4/7/8 alles prof
BeitragVerfasst: Do 15.07.04 14:27 
anton hat folgendes geschrieben:
Ok, ich habe immer gedacht, dass free ein Destruktor ist, aber du hast Recht. Das war ein Fehler. Aber was wird, wenn ich anstatt von "destructor free" "procedure free" schreibe. Dann ruft die Methode die übergeordnete Methode "Free" auf und die ruft destroy auf. das wäre dann doch richtig, oder?


Wäre möglich...ist aber unüblich, zuaml free nicht virtuell ist! Du musst nur destroy überschreiben und free aufrufen, da das stadard-free dann deinen destruktor aufruft.

_________________
mfg.
mâximôv
anton Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 16

XP, Linux
D5 Standard
BeitragVerfasst: Do 15.07.04 14:47 
Ok, so mache ich das. Danke für die Hinweise