Autor Beitrag
Fingolfin
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 20



BeitragVerfasst: So 09.03.03 15:04 
Hier mein erster Post und gleich 'ne Frage :oops:

Hallöle, ich habe ein Problem (wahrscheinlich allgemeines Verständnis) bei Klassen mit Delphi.

Ich habe das ganze mal ins Tierreich abstrahiert, um es leichter verständlich zu machen.

Ich habe jetzt also ne Klasse Katze, Tier und Hund, wobei Katze und Hund von Tier erben.


ausblenden Quelltext
1:
2:
3:
4:
5:
var 
Tier:TTier; 
begin 
Tier:=TKatze.Create; //funktioniert 
end;


Jetzt wollte ich eine Klasse Tieransammlung kreieren und dabei auf ObjectLists verzichten (Delphi 4).


ausblenden 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:
TTierAnsammlung=class 
private 
FTiere:Array of TTier; 
function GetTier(ind:Integer):TTier; 
procedure SetTier(ind:Integer;tier_:TTier); 
public 
property Tiere[ind:Integer]:TTier read GetTier write SetTier; 
end; 

implementation 

function TTieransammlung.GetTier(ind:Integer); 
begin 
if Length(FTiere)>ind then 
Result:=FTier[ind] 
else 
begin 
Result:=nil; 
end; 
end; 

procedure TTieransammlung.SetTier(ind:Integer;tier_:TTier); 
begin 
if ind<Length(FTiere) then 
begin 
SetLength(FTiere,ind+1); 
FTiere[ind]:=TTier.Create; 
end; 
end;


Jetzt funktioniert folgendes nicht:

ausblenden Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
var 
tieransammlung:TTieransammlung; 
begin 
tieransammlung.Tiere[0]:=TKatze.Create; 
//bis hierhin sagt er nix 

ShowMessage(tieransammlung.Tiere[0].Classname); 

{gibt TTieransammlung aus, hier sollte doch aber TKatze ausgegeben werden  :?  Demzufolge komme ich auch nicht an die Eigenschaften von TKatze ran} 

//Selbst: 

(Tieransammlung.Tier[0] as TKatze).beine:=5; 

//liefert mit einen Invalid Class Typecast 

end;


Vielleicht wißt ihr ja, was ich hier falsch mache.
(Meine Abschlußprüfung rückt in schreckliche Nähe :( )

Danke euch schonmal.

Fingolfin

Moderiert von user profile iconKlabautermann: Code-Tags hinzugefügt.
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: So 09.03.03 15:24 
Hi, nicht persöhnlich nehmen...aber erstma Schelte wegen der formatierung: BITTE MACH CODE-TAGS UM DEN CODE UND FORMATIERE IHN...erhöht die wahrscheinlichkeit auf antworten.

So.

ausblenden Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
procedure TTieransammlung.SetTier(ind:Integer;tier_:TTier); 
begin 
if ind<Length(FTiere) then 
begin 
SetLength(FTiere,ind+1); 
FTiere[ind]:=TTier.Create; 
end; 
end;


Ich denke du meinst hier 'grösser gleich':

ausblenden Quelltext
1:
if ind>=Length(FTiere) then					


hilft das?
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: So 09.03.03 15:30 
Achja..hab die frage nicht zu ende gelesen...ist auch echt aunstrengend :D

dein code(Tieransammlung.Tier[0] as TKatze).beine:=5;

würd ich mal so schreibenTKatze(Tieransammlung.Tier[0]).beine:=5;

hilft das ?
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: So 09.03.03 15:36 
Nochwas :roll: :
ausblenden Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
procedure TTieransammlung.SetTier(ind:Integer;tier_:TTier); 
begin 
if ind<Length(FTiere) then 
begin 
SetLength(FTiere,ind+1); 
FTiere[ind]:=TTier.Create; 
end; 
end;


Wenn 'tier_' schon created ist, dann musst du die referenz in dem array nicht instanzieren, sondern einfach zuweisen. Oder auf nil abfragen und dann createn:
ausblenden Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
procedure TTieransammlung.SetTier(ind:Integer;tier_:TTier); 
begin 
  if ind>=Length(FTiere) then 
  begin 
    SetLength(FTiere,ind+1); 
    if tier_ = nil then tier_ := TTier.Create
    FTiere[ind]:= tier_; 
  end; 
end;


?
derDoc
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 623

Win Vista Prof
D2007 Prof
BeitragVerfasst: So 09.03.03 16:57 
Versuch es doch mal mir ClassType

_________________
MfG derDoc
There are only 10 types of people: those who understand binary and those who don't.
AndyB
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 1173
Erhaltene Danke: 14


RAD Studio XE2
BeitragVerfasst: So 09.03.03 17:59 
maximus hat folgendes geschrieben:
ausblenden Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
procedure TTieransammlung.SetTier(ind:Integer;tier_:TTier); 
begin 
  if ind>=Length(FTiere) then 
  begin 
    SetLength(FTiere,ind+1); 
    if tier_ = nil then tier_ := TTier.Create
    FTiere[ind]:= tier_; 
  end; 
end;

Und was passiert hier, wenn ind < Length(FTiere) ist?

_________________
Ist Zeit wirklich Geld?
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: So 09.03.03 23:59 
@Andyb:
Na, nix *g* man kann ja nicht alles vorkauen. Der code war halt noch nicht formatiert...find ich schon unglaublich gut von mir, dass ich das entziffern konnte :wink:

ausblenden Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
procedure TTieransammlung.SetTier(ind:Integer;tier_:TTier); 
begin 
  if ind>=Length(FTiere) then 
  begin 
    SetLength(FTiere,ind+1); 
    if tier_ = nil then tier_ := TTier.Create 
    FTiere[ind]:= tier_; 
  end 
  else FTiere[ind]:= tier_; // hätt ich ihm auch selbst zugetraut
end;


bis denn. funzt et :?:

PS: Vielleicht noch auf ind < 0 abfragen.
Fingolfin Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 20



BeitragVerfasst: Mo 10.03.03 09:05 
Ja es funktioniert wunderbar. Vielen Dank für die Mühe, obwohl mir nicht 100% klar ist, wo der Unterschied liegt. Ob ich TTier jetzt extra kreiere und dann zuweise oder sofort kreiere, wie ich's vorher gemacht habe. :?:

Vielen Dank.

Und sorry wegen der Codeformatierung, ich wußte echt nicht, daß sowas geht. :oops:

Ich werd mich bessern, versprochen. :)

Fingolfin
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: Mo 10.03.03 10:55 
Naja...mit dem create: Wenn du...tieransammlung.Tiere[0]:=TKatze.Create;
...machst hast du ja schon eine instanz erstellt, die du in die liste einglidern willst. Wenn du nun in der procedure noch mal create machst, dann hast du zwei instanzen. Einmal von TKatze und einmal von TTier, wobei du dann nur die referenz auf TTier gespeichert hättest. Dh. du hättest ein SpeicherLeck, da du keine gültige Referenz auf die Instanz von TKatze hättest und das war wohl nicht dein ziel.

IMHO würd ich das create in der prozedure weg lassen, du musst dann aber immer auf NIL prüfen.

Bis denn.
Fingolfin Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 20



BeitragVerfasst: Mo 10.03.03 16:55 
Alles klar, jetzt hab ich's soweit verstanden :D

Ist mein erster Versuch mit Klassen in Delphi, da hab' ich einiges an Nachholbedarf.

Noch eine blöde Frage:

Wo ist der Unterschied zwischen:

ausblenden Quelltext
1:
(Tieransammlung.Tier[0] as TKatze).beine:=5;					


und

ausblenden Quelltext
1:
TKatze(Tieransammlung.Tier[0]).beine:=5;					


Ist doch eigentlich beides nur 'ne Typumwandlung oder?

(Jetzt hab ich's auch mit den Code-Tags kapiert. Sehr nützlich!)

Fingolfin