Delphi - 确保调用类构造函数

Sim*_*mon 7 delphi constructor class

这可能是一个简单的问题,但我想知道如何确保调用类的构造函数.

如果我有以下代码:

type TMyObject = class(TObject)
  public
     constructor Create;override;
end;

implementation 

constructor TMyObject.Create;override;
begin
  inherited;
  //do other instantiation
end;
Run Code Online (Sandbox Code Playgroud)

Delphi不允许这样 - '无法覆盖静态方法'.

我想这样做的是确保对象是使用创建了创建自定义构造函数和禁止调用祖先创建构造函数.

我目前解决这个问题的方法是定义一个唯一签名的Create构造函数,如下所示:

constructor Create(aName : String);overload;
Run Code Online (Sandbox Code Playgroud)

但程序员可能会调用祖先的Create()方法.

Cos*_*und 14

您只需重新引入具有祖先名称的构造函数.一旦你这样做,用户就无法创建TMyObject调用引入的构造函数TObject.如果你使用这样的代码:

TMyObject = class
public
  constructor Create;
end;

constructor TMyObject.Create;
begin
  // I am not calling the inherited constructor because
  // I do not want to.
end;
Run Code Online (Sandbox Code Playgroud)

您不使用override修饰符,TMyObject.Create因为祖先的构造函数不是虚拟的.

使用此方案,用户无法TMyObject使用祖先中引入的构造函数创建您的方案.在这种情况下,祖先是TObject,它是唯一的构造函数TObject.Create.如果用户编写此代码:

X := TMyObject.Create;
Run Code Online (Sandbox Code Playgroud)

很明显,TMyObject将会调用构造函数,而不是引入的构造函数TObject.


如果你害怕用户为了使用祖先的构造函数创建你的类而跳过箍,你可以用这个AfterConstruction方法做你的东西.这是一个虚方法,所以即使你的对象是使用祖先类型的类引用创建的,它也会被调用:

TMyObject = class
public
  procedure AfterConstruction;override;
end;
Run Code Online (Sandbox Code Playgroud)


Ger*_*oll 6

TObject.Create不是虚构造函数,因此是错误.

"其他程序员"可以调用祖先Create方法的唯一方法是故意跳过一些箍,这样做,例如

var
  ClassRef: TClass;
  Obj : TObject;
begin
  ClassRef := TMyObject;
  Obj := ClassRef.Create;
end;
Run Code Online (Sandbox Code Playgroud)

因为新引入的构造函数将隐藏非虚拟的 TObject.Create

你想要的可能更像是:

type TMyObject = class(TObject)
  public
     constructor Create;virtual;
end;

implementation 

constructor TMyObject.Create;
begin
  inherited;
  //do other instantiation
end;
Run Code Online (Sandbox Code Playgroud)