首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Delphi XE:我可以在不使用hacks的情况下,使用classtype约束泛型类型中的参数调用虚拟构造函数吗?

Delphi XE:我可以在不使用hacks的情况下,使用classtype约束泛型类型中的参数调用虚拟构造函数吗?
EN

Stack Overflow用户
提问于 2012-03-06 23:27:56
回答 4查看 1.2K关注 0票数 5

我正在尝试为复合控件构建一个泛型祖先。最初的想法是这样的:

代码语言:javascript
复制
type
  TCompositeControl<TControl1: TControl; TControl2: TControl> = class(TWinControl)
  private
    FControl1,
    FControl2: TControl;
  public
    constructor Create(AOwner: TComponent); override; 
  end;

  TLabelAndEdit = TCompositeControl<TLabel, TEdit>; // simple example for illustration only

constructor TCompositeControl<TControl1,TControl2>.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
  FControl1 := TControl1.Create(Self);
  FControl2 := TControl2.Create(Self);
end;

正如你可能已经知道的,这将触发编译器错误E2568:如果类型参数声明中没有构造函数约束,则无法创建新实例。然而,添加constructor约束并没有什么帮助,因为它暗示了一个无参数的构造函数。

将模板转换为TControl使代码可编译:

代码语言:javascript
复制
...
FControl1 := TControl(TControl1).Create(Self);
...

...but它会在运行时导致访问冲突。

一个可能可行的方法是通过RTTI调用构造函数,但我认为这是一个相当糟糕的解决方案。

另一个本质上有效的技巧是使用类类型变量作为中间层:

代码语言:javascript
复制
type
  TControlClass = class of TControl;

constructor TCompositeControl<TControl1,TControl2>.Create(AOwner: TComponent);
var
  lCtrlClass1,
  lCtrlClass2: TControlClass;
begin
  inherited Create(AOwner);
  lCtrlClass1 := TControl1;
  FControl1 := lCtrlClass1.Create(Self);
  lCtrlClass2 := TControl2;
  FControl2 := lCtrlClass2.Create(Self);
end;

有没有更干净的解决方案?另外,有人能给我解释一下为什么classtype约束不足以直接调用type参数上的虚拟构造函数吗?

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2012-03-06 23:51:35

你的类型转换不好:TControl(TControl1).Create(Self)。这告诉编译器TControl1TControl的一个实例,但我们知道它不是一个实例。它是一个类引用。type -将其转换为类引用类型:

代码语言:javascript
复制
FControl1 := TControlClass(TControl1).Create(Self);
票数 6
EN

Stack Overflow用户

发布于 2015-12-11 06:34:26

另一种语法是

代码语言:javascript
复制
FControl1 := TControl1(TControl1.NewInstance); // get memory for object
FControl1.Create(self); // call type-specific constructor

FControl2 := TControl2(TControl2.NewInstance); // get memory for object
FControl2.Create(self); // call type-specific constructor

这是在Delphi的Classes.pas::CreateComponent中使用的,我只是不能决定哪个选项是最不丑陋的!

票数 0
EN

Stack Overflow用户

发布于 2016-02-15 01:07:11

这似乎是最新的delphi版本(西雅图),这个编译器错误不再发出。我在我们的应用程序中遇到了同样的问题,但只有在使用DelphiXe8而不是delphi Seattle编译时才会遇到这个问题

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/9586626

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档