Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why doesn't the derived constructor get called when instantiating via a metaclass class factory?

I'm trying to create what I understand to be a Class Factory in Delphi 2007. I want to pass a derived class type into a function and have it construct an object of that class type.

I've found some good references, such as How can I create an Delphi object from a class reference and ensure constructor execution?, but I still can't get it to work quite right. In the test below, I can't get it to call the derived constructor, even though the debugger tells me that oClass is TMyDerived.

I think I'm confused about something fundamental here and could use some explanation. Thanks.

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.
like image 795
Jeff Wilson Avatar asked May 06 '11 19:05

Jeff Wilson


1 Answers

You neglected to specify override on the derived class constructor. (I would have expected a warning from the compiler about hiding the base-class method.) Add that, and you should see TMyDerived.Create called.

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

An alternative, since your constructors take no parameters, is to forgo virtual constructors and just override AfterConstruction.

like image 188
Rob Kennedy Avatar answered Sep 29 '22 07:09

Rob Kennedy