动态创建的对象(将其类名称作为字符串)不会调用其构造函数

lyb*_*rko 1 delphi delphi-7

这是对象:

TCell = class(TPersistent)
private
  FAlignmentInCell :byte;
public
  constructor Create; virtual;
published
  property AlignmentInCell:byte  read FAlignmentInCell write FAlignmentInCell;
end;
Run Code Online (Sandbox Code Playgroud)

这是它的构造函数:

constructor TCell.Create;
begin
  inherited;
  FAlignmentInCell:=5;
end;
Run Code Online (Sandbox Code Playgroud)

这是一个函数,它动态创建从TPersistent派生的任何对象(参数是以字符串形式提供的类名)

function  CreateObjectFromClassName(AClassName:string):TPersistent;
var DynamicObject:TPersistent;
    TempObject:TPersistent;
    DynamicPersistent:TPersistent;
    DynamicComponent:TComponent;
    PersistentClass:TPersistentclass;
    ComponentClass:TComponentClass;
begin
  PersistentClass:=TPersistentclass(FindClass(AClassName));
  TempObject:=PersistentClass.Create;
  if TempObject is TComponent then
         begin
         ComponentClass:=TComponentClass(FindClass(AClassName));
         DynamicObject:=ComponentClass.Create(nil);
         end;
  if not (TempObject is TComponent) then
         begin
         DynamicObject:=PersistentClass.Create; // object is really TCell, but appropriate constructor seems to be not called. 
         end;
  result:=DynamicObject;
end;
Run Code Online (Sandbox Code Playgroud)

我的想法是创建这样的新Cell(TCell):

procedure TForm1.btn1Click(Sender: TObject);
var p:TPersistent;
begin
  p := CreateObjectFromClassName('TCell');
  ShowMessage(IntToStr(TCell(p).AlignmentInCell)); // it is 0. (Why?)
end;
Run Code Online (Sandbox Code Playgroud)

当我想检查AlignmentInCell属性时,我得到0,但我预计为什么?为什么?有办法解决吗?

Rud*_*uis 5

这类似于最近的一个问题.

你用TPersistentClass.但是TPersistent没有虚构造函数,所以TPersistent调用了正常的构造函数,它是它继承的构造函数TObject.

如果要调用虚拟构造函数,则必须声明一个

type
  TCellClass = class of TCell;
Run Code Online (Sandbox Code Playgroud)

现在您可以修改CreateObjectFromClassName使用此元类而不是TPersistenClass,然后将调用实际的构造函数.

此外,TempObject永远不会被释放.而不是is,我宁愿使用InheritsFrom.

我没有测试以下内容,但它应该工作:

function CreateObjectFromClassName(const AClassName: string; AOwner: TComponent): TPersistent;
var 
  PersistentClass: TPersistentclass;
begin
  PersistentClass := FindClass(AClassName);
  if PersistentClass.InheritsFrom(TComponent) then
    Result := TComponentClass(PersistentClass).Create(AOwner)
  else if PersistentClass.InheritsFrom(TCell) then
    Result := TCellClass(PersistentClass).Create
  else
    Result := PersistentClass.Create;
end;
Run Code Online (Sandbox Code Playgroud)