Delphi 'class of' 用于创建特定类型的对象

Delphi 'class of' use to create an object of a specific type

我有 TParentObj = class(TComponent)TChildObj = class (TParentObj)。另外我还有一个TCustomObj = class of TParentObj.

然后我想根据变量是什么创建父类型或子类型的对象。如果选择 'child',则应创建 TChildObj,依此类推。

在函数中我有一个变量:obj : TCustomObj。 然后我正在尝试做:

if oReturnType = TChildObj
  obj := TChildObj.create
else if oReturnType = TParentObj
  obj := TParentObj.create

oReturnType 在别处设置并传入。

如果我使用 'is' 而不是 '=',我会收到操作符不适用于此操作数类型的错误,如果我使用 = 而不是,我会收到 TCustomObj 之间的不兼容类型错误TChildObjTParentObj.

我已经搜索了很多,但还没有发现我做错了什么,希望这里的人能够对此有所了解。

提前致谢。

您可以使用类类型TCustomObj创建实例

function ObjFactory( AClass : TCustomObj ): TParentObj;
begin
  Result := AClass.Create;
end;

procedure foo;
var
  LObj : TParentObj;
begin
  // instance of TParentObj
  LObj := ObjFactory( TParentObj );
  // or instance of TChildObj
  LObj := ObjFactory( TChildObj );
end;

首先,您似乎错过了 TClass 变量最重要的一点之一:它们可以访问构造函数和 虚拟构造函数

如果你在 TParentObj 上放置一个构造函数并将其声明为 virtual;,然后让所有后代 override;根据需要构造函数,然后声明为 class of TParentObjTClass 变量将可以访问此虚构造函数,并且其行为与您期望虚方法的行为完全相同:

obj := oReturnType.Create(); 
//invoke the virtual constructor on the actual type of oReturnType

此技术在 VCL 中广泛使用;例如,它是 Delphi 表单流系统的核心。 TComponent 定义了一个签名为(AOwner: TComponent) 的虚拟构造函数,每个需要新构造函数的自定义组件和控件都会覆盖这个构造函数。这是一个非常有用的系统,如果您了解它的工作方式,您将很快对所涉及的技术有所了解。

但至于实际问题,您在 TCustomObjTChildObjTParentObj 之间遇到类型不兼容的错误,因为 它们不兼容类型。

TChildObjTParentObjobject classesTCustomObjmetaclass,或class变量TParentObj 变量表示一个对象,而定义为 class of TParentObjTCustomObj 表示 class 本身,而不是 class 的对象。将 obj 声明为 TParentObj(它将接受 TParentObj 或其任何后代的对象实例)并且你会很好。