On Mon, 21 Aug 2006 00:56:35 +0000
Albert Zeyer <[EMAIL PROTECTED]> wrote:
> Hello,
>
> I want to use class-references (class of SOMECLASS) as a way for a
> dynamic object factory.
> First I tried it with the predefined type TClass (:= class of
> TObject), but this doesn't work, because Create is not virtual in
> TObject (it costs some time to find out that this is the problem,
> nevertheless it is logical in some way... perhaps my experiences with
> ObjectPascal are to small). So I tried the following and it works as
> I want:
>
> // ---------------------------------------------
> ...
> type
> TBaseTestObject = class
> constructor Create(); virtual;
> end;
>
> TBaseTestClass = class of TBaseTestObject;
>
> TTestObject = class(TBaseTestObject)
> public
> constructor Create(); override;
> destructor Destroy(); override;
> end;
>
>
> TSkriptTestForm = class(TForm)
> Button1: TButton;
> procedure Button1Click(Sender: TObject);
> mTest: TTestObject;
> end;
>
> procedure TSkriptTestForm.Button1Click(Sender: TObject);
> var
> cls: TBaseTestClass;
> begin
> cls := TTestObject;
> mTest := cls.Create() as TTestObject;
> end;
>
> constructor TBaseTestObject.Create();
> begin
> // is this needed? it calls TObject.Create, but what does it?
> inherited Create();
No. But it maybe better for future extensions.
> WriteLn('TBaseTestObject Create');
> end;
>
> constructor TTestObject.Create();
> begin
> inherited Create();
>
> WriteLn('TTestObject Create');
> end;
>
> destructor TTestObject.Destroy();
> begin
> WriteLn('TTestObject Destroy');
>
> inherited Destroy();
> end;
>
> // ---------------------------------------------
>
> But is there an easier way than this, so that I can use simply TClass?
Probably not. It depends on what you want to achieve.
> I think, RTTI is very powerfull and there should be a way to do the
> same as above without a virtual constructor. But is it clean?
To use RTTI you must derive from TPersistent or use the {$M+} directive.
> In practice, I have a abstract base class with a function like this:
>
> function TMyBase.CreateCopy(): TMyBase;
> begin
> Result := Self.ClassType.Create(); // this doesn't work because
> ClassType is a TClass
> // TODO: fill the result with same data ...
> end;
With TPersistent it would work like this
TMyBase = class(TPersistent)
public
function CreateCopy: TMyBase;
procedure Assign(Source: TPersistent); override;
end;
it would be
function TMyBase.CreateCopy: TMyBase;
begin
Result := TMyBaseClass(Self.ClassType).Create;
Result.Assign(Self);
end;
Every class must override the Assign method to copy all added values.
Another possibility:
Use TComponent as base class. Then you can copy without writing the
Assign procedures. The IDE uses this. It is much
slower than the Assign approach.
Mattias
_________________________________________________________________
To unsubscribe: mail [EMAIL PROTECTED] with
"unsubscribe" as the Subject
archives at http://www.lazarus.freepascal.org/mailarchives