|
| Typecast-fejl Fra : Poul |
Dato : 23-01-05 20:13 |
|
Hej NG
Jeg sidder med et større projekt og kan ikke komme videre pga. en typecast
fejl
For at få oveblik og løse den, har jeg konstrueret et mindre model-projekt
af min klasse-system, som ser følgende ud:
1).
TBase = class
value : integer;
procedure Call; virtual; abstract;
end;
TDerived = class (TBase)
value : integer;
procedure Call; override; // implementeret
end;
Under programmes forløb oprettes der objekter af typen TDerived, og pointers
gemmes i en TList. Et andet sted i koden kalder jeg disse objekt(er) fra
listen, som den oprindelige base type..
2).
var temp : TBase;
temp := TBase( List[0] );
temp.Call;
Jeg kan (og behøver) ikke at vide, hvilken type objekter fra TList'en er, da
alle de nedarvede objekter har en fælles procedure Call, som jeg kan kalde
uden at tænke på implementationen.
Det hele fungerer fint, indtil jeg prøver at overføre base obektens
egenskaber til en derived objekt ved hjælp af typecast:
3).
baseObj := TBase.Create;
baseObj.value:=25
derivedObj := TDerived.Create;
derivedObj := (baseObj as TDerived); //eller: TBase(derivedObj) :=
baseObj;
List.Add(derivedObj);
Så virker kode 2) ikke, og jeg får en "Abstract Error", som er en resultat
af kaldet til en abstakt metode Call i TBase. Men sådan burde det ikke være,
da det er en Derived objekt jeg tilføjer til listen (selv om den har fået
baseObjektens egenskaber)
Jeg kunne selvfølgelig overføre alle variableværdier manuelt, i stedet for
at typecaste dem, men jeg mener at der må være en nemmere måde at gøre det
på. (som f.eks. static_typecast i c++)
Er der nogen der kan hjælpe?
--
Med Venlig Hilsen
Poul
| |
Thor (23-01-2005)
| Kommentar Fra : Thor |
Dato : 23-01-05 22:57 |
|
Hej Poul
Det her virker ihvertfald:
unit Unitderive;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
type
TForm1 = class(TForm)
Label1: TLabel;
Label2: TLabel;
procedure FormCreate(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
type
TBase = class
procedure Call; virtual; abstract;
end;
TDerived1 = class (TBase)
procedure Call; override;
end;
procedure tderived1.call;
begin
form1.label1.Caption := 'Derived1';
end;
type
TDerived2 = class (TBase)
procedure Call; override;
end;
procedure tderived2.call;
begin
form1.label2.Caption := 'Derived2';
end;
var temp : TBase;
der1 : tderived1;
der2 : tderived2;
list : tlist;
procedure TForm1.FormCreate(Sender: TObject);
begin
list := tlist.create;
der1 := tderived1.create;
der2 := tderived2.create;
List.Add(der1);
List.Add(der2);
tbase(list[0]).call;
tbase(list[1]).call;
end;
end.
| |
Poul (24-01-2005)
| Kommentar Fra : Poul |
Dato : 24-01-05 09:33 |
|
"Thor" <thor@thor.thor> skrev i en meddelelse
news:ct16hs$15p$1@news.cybercity.dk...
> procedure TForm1.FormCreate(Sender: TObject);
> begin
>
> list := tlist.create;
> der1 := tderived1.create;
> der2 := tderived2.create;
> List.Add(der1);
> List.Add(der2);
>
> tbase(list[0]).call;
> tbase(list[1]).call;
> end;
> end.
Tak for svaret, jeg kan se at grunden til min fejl er at jeg prøvede at
overføre egenskaber fra en TBase Objekt, som har ikke en implementation for
Call, og derfor umuligt at kalde efter typecasten.
Så til dem der begår samme fejl - lad være med at initializere base-klassen
og brug den kun til at kalde de nedarvede objeker, som:
tbase(list[0]).call;
--
Mvh. poul
| |
|
|