【问题标题】:Why doesn't the derived constructor get called when instantiating via a metaclass class factory?为什么通过元类类工厂实例化时不调用派生构造函数?
【发布时间】:2011-05-06 19:25:20
【问题描述】:

我正在尝试在 Delphi 2007 中创建我所理解的类工厂。我想将派生类类型传递给函数并让它构造该类类型的对象。

我找到了一些很好的参考资料,例如How can I create an Delphi object from a class reference and ensure constructor execution?,但我仍然无法让它正常工作。在下面的测试中,我无法让它调用派生构造函数,即使调试器告诉我 oClass 是 TMyDerived。

我想我对这里的基本内容感到困惑,可以使用一些解释。谢谢。

program ClassFactoryTest;
{$APPTYPE CONSOLE}
uses
  SysUtils;

//  BASE CLASS
type
  TMyBase = class(TObject)
    bBaseFlag : boolean;
    constructor Create; virtual;
  end;
  TMyBaseClass = class of TMyBase;

constructor TMyBase.Create;
begin
  bBaseFlag := false;
end;

//  DERIVED CLASS
type
  TMyDerived = class(TMyBase)
    bDerivedFlag : boolean;
    constructor Create;
  end;

constructor TMyDerived.Create;
begin
  inherited;
  bDerivedFlag := false;
end;

var
  oClass: TMyBaseClass;
  oBaseInstance, oDerivedInstance: TMyBase;
begin
  oClass := TMyBase;
  oBaseInstance := oClass.Create;

  oClass := TMyDerived;
  oDerivedInstance := oClass.Create;  // <-- Still calling Base Class constructor
end.

【问题讨论】:

    标签: delphi class constructor


    【解决方案1】:

    您忽略了在派生类构造函数上指定override。 (我本来希望编译器会发出关于隐藏基类方法的警告。)添加它,您应该会看到 TMyDerived.Create 被调用。

    TMyDerived = class(TMyBase)
      bDerivedFlag : boolean;
      constructor Create; override;
    end;
    

    由于您的构造函数不带参数,另一种选择是放弃虚拟构造函数并覆盖AfterConstruction

    【讨论】:

    • +1,但是...is to forgo virtual constructors and just override AfterConstruction. 呃,非常令人困惑的非标准。请坚持使用构造函数
    • 使用AfterConstruction 的唯一问题是它没有明确意图。子类化和添加非重写构造函数很容易。虚拟构造函数清楚地说明了这一点。也就是说,如果您犯了这个错误,您的代码将无法正常工作,我一直认为这是一个很好的安全网!
    猜你喜欢
    • 2020-07-02
    • 2013-01-28
    • 2013-06-08
    • 1970-01-01
    • 1970-01-01
    • 2015-07-18
    • 2016-07-19
    • 2021-05-24
    • 2022-07-01
    相关资源
    最近更新 更多