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
之间的不兼容类型错误TChildObj
和 TParentObj
.
我已经搜索了很多,但还没有发现我做错了什么,希望这里的人能够对此有所了解。
提前致谢。
您可以使用类类型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 TParentObj
的 TClass
变量将可以访问此虚构造函数,并且其行为与您期望虚方法的行为完全相同:
obj := oReturnType.Create();
//invoke the virtual constructor on the actual type of oReturnType
此技术在 VCL 中广泛使用;例如,它是 Delphi 表单流系统的核心。 TComponent
定义了一个签名为(AOwner: TComponent)
的虚拟构造函数,每个需要新构造函数的自定义组件和控件都会覆盖这个构造函数。这是一个非常有用的系统,如果您了解它的工作方式,您将很快对所涉及的技术有所了解。
但至于实际问题,您在 TCustomObj
与 TChildObj
和 TParentObj
之间遇到类型不兼容的错误,因为 它们不兼容类型。
TChildObj
和 TParentObj
是 object classes,TCustomObj
是 metaclass,或class变量。 TParentObj
变量表示一个对象,而定义为 class of TParentObj
的 TCustomObj
表示 class 本身,而不是 class 的对象。将 obj
声明为 TParentObj
(它将接受 TParentObj
或其任何后代的对象实例)并且你会很好。
我有 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
之间的不兼容类型错误TChildObj
和 TParentObj
.
我已经搜索了很多,但还没有发现我做错了什么,希望这里的人能够对此有所了解。
提前致谢。
您可以使用类类型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 TParentObj
的 TClass
变量将可以访问此虚构造函数,并且其行为与您期望虚方法的行为完全相同:
obj := oReturnType.Create();
//invoke the virtual constructor on the actual type of oReturnType
此技术在 VCL 中广泛使用;例如,它是 Delphi 表单流系统的核心。 TComponent
定义了一个签名为(AOwner: TComponent)
的虚拟构造函数,每个需要新构造函数的自定义组件和控件都会覆盖这个构造函数。这是一个非常有用的系统,如果您了解它的工作方式,您将很快对所涉及的技术有所了解。
但至于实际问题,您在 TCustomObj
与 TChildObj
和 TParentObj
之间遇到类型不兼容的错误,因为 它们不兼容类型。
TChildObj
和 TParentObj
是 object classes,TCustomObj
是 metaclass,或class变量。 TParentObj
变量表示一个对象,而定义为 class of TParentObj
的 TCustomObj
表示 class 本身,而不是 class 的对象。将 obj
声明为 TParentObj
(它将接受 TParentObj
或其任何后代的对象实例)并且你会很好。