Yet another in my series of questions regarding constructors in Delphi.
i have a base class that has has the virtual constructor:
TComputer = class(TObject)
public
constructor Create(Teapot: Integer); virtual;
end;
The constructor is virtual for the times that someone needs to call
var
computerClass: class of TComputer;
computer: TComputer;
begin
computer := computerClass.Create(nTeapot);
The constructor is overridden
in descendants:
TCellPhone = class(TComputer)
public
constructor Create(Teapot: Integer); override;
end;
TiPhone = class(TCellPhone )
public
constructor Create(Teapot: Integer); override;
end;
Where TCellPhone
and TiPhone
descendants each have their opportunity to do their own initialization (of members not included for readability).
But now i add an overloaded constructor to some ancestor:
TCellPhone = class(TComputer)
public
constructor Create(Teapot: Integer); override; overload;
constructor Create(Teapot: Integer; Handle: string); overload;
end;
The alternate constructor in TCellPhone calls the other virtual constructor, so it always gets the proper overridden behaviour:
constructor TCellPhone.Create(Teapot: Integer; Handle: string);
begin
TCellPhone.Create(Teapot); //call sibling virtual constructor
FHandle := Handle;
end;
The problem is that the descendant, overridden, constructor is never called. The actual stack trace chain of calls is:
phone := TiPhone.Create(37, 'spout')
constructor TCellPhone.Create(Teapot: Integer; Handle: string)
constructor TCellPhone.Create(Teapot: Integer)
constructor TComputer.Create(Teapot: Integer)
TObject.Create
The sibling call to TCellPhone.Create(int)
, which is virtual, should have called the descendant, overridden, method in TiPhone
:
phone := TiPhone.Create(37, 'spout')
constructor TCellPhone.Create(Teapot: Integer; Handle: string)
constructor TiPhone.Create(Teapot: Integer)
constructor TCellPhone.Create(Teapot: Integer)
constructor TComputer.Create(Teapot: Integer)
TObject.Create
So it seems that attempts to use a sibling virtual constructor is Delphi do not work as expected.
Is it then a bad idea for one constructor to use another? Is the design intention that code in overloaded constructors be copy-paste versions of each other?
i notice in .NET that some constructors chain to each other:
public Bitmap(int width, int height) : this(width, height, PixelFormat.Format32bppArgb) {}
public Bitmap(int width, int height, PixelFormat format) {...}
This only seems to be a problem if:
- a constructor is virtual
- you overload the constructors
Is the rule that you cannot have one constructor overload another?