Entwickler-Ecke

Delphi Language (Object-Pascal) / CLX - Zugriff auf Eigenschaft eines übergeordneten Objektes


TillW - Do 11.03.04 15:23
Titel: Zugriff auf Eigenschaft eines übergeordneten Objektes
Mein Problem ist folgendes:
Ich will auf eine Eigenschaft des übergeordneten Objektes zugreifen. Das habe ich mit der Eigenschaft Parent versucht:


Delphi-Quelltext
1:
2:
Objekt.Create(...);
Objekt.Parent := self;


Bei der unteren Zuweisung bekomme ich eine EAccesViolation bei der Adresse "00000000..".
Die Objekte sind alle von der Klasse TWinControl.


Motzi - Do 11.03.04 17:05

Ein Objekt erzeugst du folgendermaßen:

Delphi-Quelltext
1:
Objekt := TObjektKlasse.Create(..);                    

Ein solcher Aufruf:

Delphi-Quelltext
1:
Objekt.Create(..)                    

Ruft zwar auch Create auf, allerdings als normale Methode des Objekts "Objekt" und nicht als Konstruktur der Klasse "TObjektKlasse"...


TillW - Fr 12.03.04 18:11

Hmm. das war wohl ein Tippfehler. Im Programm habe ich das schon richtig gemacht. Das Objekt wird auch problemlos erstellt nur ist die Eigenschaft .Parent = nil (wohl die Standardeinstellung) und die Zuweisung löst die Exception aus.
Trotzdem Danke für die Hilfe. Hier ist nochmal die Problemzeile


Delphi-Quelltext
1:
2:
Objekt := OkjektKlasse.Create(...);
Objekt.Parent := self;


Aus irgendeinem Grund muss Delphi über das 'self' stolpern, denn wenn ich statt 'self' etwas anderes zuweisen will klappt das Problemlos.


Motzi - Fr 12.03.04 18:29

Hm.. zeig mal ein bisschen mehr von deinem echten Code.. nicht nur so Pseudocode.. ;) Sonst wird eine Fehleranalyse eher schwer...


TillW - Fr 12.03.04 19:26

Hier kommen zwei Units des bisher sechs Units schweren Programms.

Erläuterung:
Das Objekt der Klasse TStaat (1. Unit) erschafft ein Objekt des Typs TIndustrie (2. Unit). Hierbei soll nach dem erschafffen dem neuen Objekt ein 'Parent' zugewiesen werden, und zwar das TStaat-Objekt. Diese Stelle habe ich rot markiert, denn sie funktioniert so nicht.
Das Objekt der Klasse TIndustrie soll dann wiederrum drei Objekte der Klasse TIndustriezweig (abgel. von TIndustrie und auch 2. Unit) erschaffen und sich als Parent zuweisen (Der Code hierfür fehlt noch da ja die erste Parent-Zuweisung net mal geklappt hat). Dieses TIndustriezweig-Objekt soll dann auf die Eigenschaft 'Einwohner' des zwei Ebenen übergeordneten TStaat-Objekt zugreifen. Diese Stelle befindet sich in der Letzten Zeile der 2. Unit und konnte bisher noch nicht auf Funktion getestet werden.

Wenn du noch andere Units brauchst poste ich die natürlich auch.
Schonmal Danke für den Aufwand, Gruß Till


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:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
92:
93:
94:
95:
96:
97:
98:
99:
100:
101:
102:
103:
104:
105:
106:
107:
108:
109:
110:
111:
112:
113:
114:
115:
116:
117:
118:
119:
120:
121:
122:
123:
124:
125:
126:
127:
128:
129:
130:
131:
132:
133:
134:
135:
136:
137:
138:
139:
140:
141:
142:
143:
144:
145:
146:
147:
148:
149:
150:
151:
152:
153:
154:
155:
156:
157:
158:
159:
160:
161:
162:
163:
164:
165:
166:
167:
168:
169:
170:
171:
172:
173:
174:
175:
176:
177:
178:
179:
180:
181:
182:
183:
184:
185:
186:
187:
188:
189:
190:
191:
192:
193:
194:
195:
196:
197:
198:
199:
200:
201:
unit uStaat;

interface

uses classes,uIndustrieZweig,controls;

type
    TStaat = class(TWinControl)

public
      Industrie : TIndustrie;
      Kapital, Einwohner : integer;

      constructor Create(StartKapital,SEinwohner:integer;WelcherStaat:string); virtual;
      procedure RundeBerechnen(StaatContainer:TStaat);
      procedure AttributeBerechnen;
end;


implementation

constructor TStaat.Create(StartKapital,SEinwohner:integer;WelcherStaat:string);
begin
     Kapital := Startkapital;
     Einwohner := SEinwohner;


     <span style="color: red">Industrie := TIndustrie.Create(WelcherStaat,'Parent',true);
     Industrie.parent := self;</span>
end;

procedure TStaat.RundeBerechnen(StaatContainer:TStaat);
begin


end;

procedure TStaat.AttributeBerechnen;
begin
     //IInvest.SpeziellAttributeBerechnen;
end;



end.






// Ende der ersten Unit







unit uIndustrieZweig;

interface

uses classes,sysutils,uMethoden,comctrls,controls;

type
    TIndustrie = class(TWinControl)
private
       ObParent : Boolean;
       procedure IntegerLaden(WelcherStaat,WelcherZweig:string);
       procedure ZweigeErstellen(WelcherStaat:string);
public
       IInvest,IKonsum,IRuest : TIndustrie;

      // InsustrieAttribute
      Struktur, LeistungsWert : integer;
      Effizienz, Auslastung, Qualitaet : integer;
      Vielfalt, Preisniveau, NachfrageVolk, NachfrageStaat, NachfrageAusland : integer;
      NachfrageGesamt : integer;

      constructor Create(WelcherStaat,WelcherZweig:string;IstParent:boolean); virtual;

      // Attributeberechnen ist für TIndustrie und TIndustriezweig verschieden
      procedure AttributeBerechnen; virtual;
end;

type
    TIndustriezweig = class(TIndustrie)
public
      procedure AttributeBerechnen; override;
end;

implementation


// Methoden für Klasse TIndustrie
constructor TIndustrie.Create(WelcherStaat,WelcherZweig:string;IstParent:boolean);
begin
     inherited Create(nil);

     // Startwerte Einlesen oder ZweigeErstellen
     If IstParent then ZweigeErstellen(WelcherStaat)
        else IntegerLaden(WelcherStaat,WelcherZweig);

     AttributeBerechnen;
end;



//   Läd Werte aus eine Textdatei
//
procedure TIndustrie.IntegerLaden(WelcherStaat,WelcherZweig:string);
var Anfang,Ende : integer;
    Methoden : TMethoden;
begin
     Methoden := TMethoden.Create;

     // Zeile vom Staatenblock
     Anfang := Methoden.DatenTitelFinden(WelcherStaat,'Data\Startwerte.txt');
     Ende := Methoden.DatenTitelFinden('end '+WelcherStaat,'Data\Startwerte.txt');

     // Zeile vom WertBlock in den Grenzen des Staatenblocks
     Anfang := Methoden.DatenTitelFinden(WelcherZweig,'Data\Startwerte.txt',Anfang,Ende);
     Ende := Methoden.DatenTitelFinden('end '+WelcherZweig,'Data\Startwerte.txt',Anfang,Ende);


     Struktur := Methoden.EigenschaftLaden('Struktur','Data\Startwerte.txt',Anfang,Ende);
     Effizienz := Methoden.EigenschaftLaden('Effizienz','Data\Startwerte.txt',Anfang,Ende);
     Qualitaet := Methoden.EigenschaftLaden('Qualitaet','Data\Startwerte.txt',Anfang,Ende);
     Preisniveau := Methoden.EigenschaftLaden('Preisniveau','Data\Startwerte.txt',Anfang,Ende);
     Vielfalt := Methoden.EigenschaftLaden('Vielfalt','Data\Startwerte.txt',Anfang,Ende);
     Auslastung := Methoden.EigenschaftLaden('Auslastung','Data\Startwerte.txt',Anfang,Ende);
     NachfrageVolk := Methoden.EigenschaftLaden('NachfrageVolk','Data\Startwerte.txt',Anfang,Ende);
     NachfrageStaat := Methoden.EigenschaftLaden('NachfrageStaat','Data\Startwerte.txt',Anfang,Ende);
     NachfrageAusland := Methoden.EigenschaftLaden('NachfrageAusland','Data\Startwerte.txt',Anfang,Ende);

     Methoden.Destroy;
end;


procedure TIndustrie.AttributeBerechnen;
var i : integer;
    IndustriezweigContainer : Array[1..3of TIndustriezweig;
begin
     IInvest.AttributeBerechnen;
     IKonsum.AttributeBerechnen;
     IRuest.AttributeBerechnen;

     IndustriezweigContainer[1] := TIndustriezweig(IInvest);
     IndustriezweigContainer[2] := TIndustriezweig(IKonsum);
     IndustriezweigContainer[3] := TIndustriezweig(IRuest);


     // Additionswerte
     For i := 1 to 3 do
     begin
          NachfrageVolk := NachfrageVolk + IndustriezweigContainer[i].NachfrageVolk;
          NachfrageStaat := NachfrageStaat + IndustriezweigContainer[i].NachfrageStaat;
          NachfrageAusland := NachfrageAusland + IndustriezweigContainer[i].NachfrageAusland;
          Struktur := Struktur + IndustriezweigContainer[i].Struktur;
          Effizienz := Effizienz + IndustriezweigContainer[i].Effizienz;
          LeistungsWert := LeistungsWert + IndustriezweigContainer[i].LeistungsWert;
          Vielfalt := Vielfalt + IndustriezweigContainer[i].Vielfalt;
          NachfrageGesamt := NachfrageGesamt + IndustriezweigContainer[i].NachfrageGesamt;
     end;

     // Durchschnittswerte
     Vielfalt := round(Vielfalt/3);
     Effizienz := round(Effizienz/3);
end;

//
// Hier werden die 3 TIndustriezweig Objekte erstellt, die dann auf die TStaat Eigenschaft zugreifen sollen
//

procedure TIndustrie.ZweigeErstellen(WelcherStaat:string);
begin
     IInvest := TIndustriezweig.Create(WelcherStaat,'Invest',false);
     IInvest.Name := 'IInvest';

     IKonsum := TIndustriezweig.Create(WelcherStaat,'Konsum',false);
     IKonsum.Name := 'IKonsum';

     IRuest := TIndustriezweig.Create(WelcherStaat,'Ruest',false);
     IRuest.Name := 'IRuest';
end;

// Methoden für TIndustriezweig
procedure TIndustriezweig.AttributeBerechnen;
var ParentNode : TTreeNode;
begin
     Leistungswert := round((Effizienz/100)*Struktur);
     NachfrageGesamt := NachfrageVolk+NachfrageStaat+NachfrageAusland;

     If Name = 'IKonsum' then
     begin
          //NachfrageVolk := Parent.Parent.Einwohner
     end;
end;

end.