Board index » delphi » About class functions and class reference types

About class functions and class reference types

Hi everybody,

yesterday I came across class methods and classreference types. This
seems
to be a quite   difficult matter, so I decided to make a posting:

Suppose you have the following classes

type

TA = class(TObject)
        a : Integer;
        constructor Create;
        procedure copy(dst : TObject); virtual;
        function dup: TObject; virtual;
        class function CreateInstance : TObject;
        end;

TB= class(TA)
        b: Integer;
        constructor Create;
        procedure copy(dst : TObject); override;
        end;

implementation

constructor TA.Create;
begin
Inherited;
a := 1;
end;

procedure TA.copy(dst : TObject);
begin
TA(dst).a = a;
end;

class function TA.CreateInstance: TObject;
begin
Result := Self.Create;
end;

function TA.dup: TObject;
var
tt : TObject;
begin
tt := Self.CreateInstance;
copy(tt);
Result := tt;
end;

constructor TB.Create;
begin
Inherited;
b:= 2
end;

procedure TB.copy(dst : TObject);
begin
Inherited;
TB(dst).b = b;
end;

Quote
>From my point of view, this would allow me to do the following:

var
A1, A2 : TA;
B1, B2 : TB;
begin

A1 := TA.Create;
B1 := TB.Create;

A2 := A1.dup;

(*
A1.dup would call 'class function' CreateInstance creating A new TA
instance
and copying the contents
*)

B2 := B1.dup;

(*
B1.dup would call 'class function' CreateInstance from class TA. In this
case
'self' should be the callers 'class reference type' (TB) therefore I
would
expect to create a new instance of TB where the contents of B1 is
copyed.

This would be a very powerfull feature because TA is able to create new
instances of any descendant without typechecking
*)

The interesting part is the 'class function' because it implicitly
creates
an object of the correct type!

-->

class function TA.CreateInstance: TObject;
begin
Result := Self.Create; //Self is the calling 'class reference type'
//eg. any TA  descendant
end;

Well, actually it is not working! This function allway calls TA.Create
only!
This is really strange, since the de{*word*81} showed

tt.classname = 'TB'

after calling

tt := Self.CreateInstance;

There is no need to define a class reference function to do so. Since
OOL
has access to RTTI I feel, that this feature should be possible. Any
hints?

Marco.

================================
Metamorphosis:

Unix verstehen.
        You nix verstehen.
                Yo! Nix verstehen!

 

Re:About class functions and class reference types


You usually do this with a virtual constructor like:

TA=class
public
    constructor Create; virtual;
    function dup:TA;
end;

TB=class
public
    constructor Create; override;
end;

implementation

constructor TA.Create;
begin
    inherited Create;
end;

function TA.dup:TA;
begin
    result:=TA(ClassType).Create;  // this is the key!!!
end;

constructor TB.Create;
begin
    inherited Create;
end;

ClassType returns a class reference to the instance and since the create
constructor is virtual the proper one will be called to create the new
instance as the proper class.

Bob Lee

Re:About class functions and class reference types


Quote
Robert Lee wrote:

> You usually do this with a virtual constructor like:

> TA=class
> public
>     constructor Create; virtual;
>     function dup:TA;
> end;

>...

> implementation

> function TA.dup:TA;
> begin
>     result:=TA(ClassType).Create;  // this is the key!!!
> end;

Sorry Bob, it did not work. I liked the idea about the virtual
constructor. I have the impression something is still missing.

TA(ClassType).Create;

Would not compile.

TA(ClassType.Create)

Would.

I even ran the de{*word*81}. At some point the debuger showed

ClassType = TB!

But TB.Create was never called!

Perhaps you have anopther idea?

Regards. Marco

Re:About class functions and class reference types


Marco Machicao y Priemer wrote:

Quote
> Sorry Bob, it did not work. I liked the idea about the virtual
> constructor. I have the impression something is still missing.

> TA(ClassType).Create;

Oops.  I forgot this:

type
    TAClass=class of TA;

...

    result:=TAClass(ClassType).Create;

There!

Bob Lee

Other Threads