了解构造函数可见性

时间:2010-10-08 17:44:17

标签: delphi constructor delphi-5 constructor-chaining

这是两个简单的类,最初都没有关键字(虚拟,重载,覆盖,重新引入):

TComputer = class(TObject)
public
   constructor Create(Teapot: Integer);
end;

TCellPhone = class(TComputer)
public
   constructor Create(Teapot: Integer; Handle: string);
end;

我会将上述定义表示为略短一些:

TComputer = class(TObject)
   constructor Create(Teapot: Integer);

TCellPhone = class(TComputer)
   constructor Create(Teapot: Integer; Handle: string);

构建TCellPhone时,只有一个构造函数(intstring) - 因为祖先构造函数已被隐藏。我将TCellPhone的可见构造函数表示为:

  • 茶壶:整数;句柄:字符串

现在提出问题,前3个案例有意义,第4个案例没有:

1。祖先构造函数由后代隐藏:

TComputer = class(TObject)
   constructor Create(Teapot: Integer);

TCellPhone = class(TComputer)
   constructor Create(Teapot: Integer; Handle: string);
  • Teapot: Integer; Handle: string

这是有道理的,祖先构造函数是隐藏的,因为我已经声明了一个新的构造函数。

2。祖先虚拟构造函数由后代隐藏:

TComputer = class(TObject)
   constructor Create(Teapot: Integer); virtual;

TCellPhone = class(TComputer)
   constructor Create(Teapot: Integer; Handle: string);
  • Teapot: Integer; Handle: string

这是有道理的,祖先构造函数是隐藏的,因为我已经声明了一个新的构造函数。

  

注意:因为祖先是虚拟的:德尔福会警告你   你隐藏了虚拟祖先(in   上一个隐藏的例子   静态构造函数:没人关心,所以   没有警告)。警告可以是   压抑(意思是“是啊是啊是的,   我正在隐藏一个虚拟构造函数。一世   意味着这样做。“)添加重新引入

    TComputer = class(TObject)
       constructor Create(Teapot: Integer); virtual;

    TCellPhone = class(TComputer)
       constructor Create(Teapot: Integer; Handle: string); reintroduce;

3。由于重载而没有隐藏在后代中的祖先构造函数:

TComputer = class(TObject)
   constructor Create(Teapot: Integer);

TCellPhone = class(TComputer)
   constructor Create(Teapot: Integer; Handle: string); overload;
  • Teapot: Integer; Handle: string
  • Teapot: Integer

这是有道理的,因为后代构造函数是祖先的重载,因此允许两者都存在。祖先构造函数未被隐藏。

4。虚拟祖先构造函数未隐藏在后代中,因为重载 - 但仍然会收到警告

这种情况毫无意义:

TComputer = class(TObject)
   constructor Create(Teapot: Integer); virtual;

TCellPhone = class(TComputer)
   constructor Create(Teapot: Integer; Handle: string); overload;
  • Teapot: Integer; Handle: string
  • Teapot: Integer

    方法'创建'隐藏基本类型'TComputer'的虚拟方法

这没什么意义。不仅隐藏了 的祖先,后代也被重载;它甚至不应该 抱怨。

是什么给出了?

3 个答案:

答案 0 :(得分:5)

Delphi的文档说:

  

如果重载虚拟方法,请使用   当你重新引入指令   在后代班级重新宣布它。   例如,

type
  T1 = class(TObject)
    procedure Test(I: Integer); overload; virtual;
  end;
  T2 = class(T1)
    procedure Test(S: string); reintroduce; overload;
  end;

如果没有重新引入指令,它仍然有效,正如您所注意到的那样,但您会收到警告。

此外,您实际上是在隐藏TObject.Create,但它与警告无关。如果您认为您可能还想访问TObject.Create,请执行以下操作:

type
  TComputer = class(TObject)
    constructor Create(Teapot: Integer); reintroduce; overload; virtual;
  end;

type
  TCellPhone = class(TComputer)
    constructor Create(Teapot: Integer; Handle: String); reintroduce; overload;
  end;

答案 1 :(得分:2)

我同意特立尼达的观点。警告背后的逻辑可能只关注祖先方法是虚拟/动态以及后代方法是否被标记为覆盖或重新引入。

这也适用于“正常”方法。

可以通过将reintroduce放在overload修饰符之前,或者通过将一个重写的构造函数添加到简单地委托给祖先构造函数的后代类来抑制它。

答案 2 :(得分:1)

我已经注意到了。据我所知,警告是一个错误,因为未隐藏继承的方法。 如果还没有,请在qc.embarcadero.com上报告。