same - why constructor cannot be inherited in c++




Need I to put overload or override words after the constructor declaration in derived class? (4)

As far as I know, there are two separate issues here:

Making sure the child class' constructor calls the base class' constructor

You'll have to explicitly call the base class' constructor:

constructor TMinMatrix.Create(Rows, Cols: Byte);
begin
   inherited;
   //...
end;

Making sure the child class' constructor overrides the base class' constructor

You'll also have to make the child class' constructor override, and the base class' constructor virtual, to make sure the compiler sees the relation between the two. If you don't do that, the compiler will probably warn you that TMinMatrix's constructor is "hiding" TMatrix's constructor. So, the correct code would be:

type
TMatrix = class
    protected
      //...
    public
      constructor Create(Rows, Cols: Byte); virtual;    // <-- Added "virtual" here
      //...
type
  TMinMatrix = class(TMatrix)
    private
      //...
    public
      constructor Create(Rows, Cols: Byte); override;   // <-- Added "override" here
      constructor CreateCopy(var that: TMinMatrix);
      destructor Destroy; override;                     // <-- Also make the destructor "override"!
  end;

Note that you should also make your destructor override.

Introducing a constructor with different parameters

Note that you can only override a constructor with the same parameter list. If a child class needs a constructor with different parameters, and you want to prevent the base class' constructors from being called directly, you should write:

type
TMyMatrix = class(TMatrix)
//...
public
  constructor Create(Rows, Cols, InitialValue: Byte); reintroduce; virtual;
//...
end

implementation

constructor TMyMatrix.Create(Rows, Cols, InitialValue: Byte);
begin
  inherited Create(Rows, Cols);   // <-- Explicitly give parameters here
  //...
end;

I hope this makes things more clear... Good luck!

I have a class hierarchy, this one:

type
TMatrix = class
    protected
      //...
    public
      constructor Create(Rows, Cols: Byte);
    //...
type
  TMinMatrix = class(TMatrix)
    private
      procedure Allocate;
      procedure DeAllocate;
    public
      constructor Create(Rows, Cols: Byte);
      constructor CreateCopy(var that: TMinMatrix);
      destructor Destroy;
  end;

So as you see, both derived and base class constructors have the same parameter list. I explicitly call base class constructor from derived one:

constructor TMinMatrix.Create(Rows, Cols: Byte);
begin
   inherited;
   //...
end;

Is it necessary to explicitly call base class constructor in Delphi? May be I need to put overload or override to clear what I intend to do? I know how to do it in C++ - you need explicit call of a base class constructor only if you want to pass some parameters to it - but I haven`t much experience in Delphi programming.


Overload, tells the compiler that a method has the same name with different parameters.

Override, tells the compiler that a method overrides it virtual or dynamic declared in the base class.

Reintroduce, will hide the virtual or dynamic method declared in the base class.

Theses definitions are from Ray Lischner's book {Delphi in a nutshell}

type
  TFirst = class
  private
    FValue: string;
    FNumber: Integer;
  public
    constructor Create(AValue: string; ANumber: integer);

    property MyValue: string read FValue write FValue;
    property MyNumber: Integer read Fnumber write FNumber; 
  end;

  TSecond = class(TFirst)
  public
    constructor Create(AValue: string; ANumber: Integer);
  end;

constructor TFirst.Create(AValue: string; ANumber: integer);
begin
  MyValue := AValue;
  MyNumber := ANumber;
end;

{ TSecond }

constructor TSecond.Create(AValue: string; ANumber: Integer);
begin
  inherited;
end;

The TSecond as it is declared will call the create of the TFirst, without the inherited, the TSecond members stay empty.


You need to call the inherited method explicitly; Delphi won't do it for you. This is by design, because there are cases where you're working with virtual methods, for example, when you do not want to invoke the inherited behavior.

Also, as a matter of personal preference, I like to write out the inherited call completely. (inherited Create(Rows, Cols); as opposed to just inherited; for one simple reason: it makes it that much easier to traverse the code. If you've got a method call written out, you can control-click it and get to the ancestor method.


Overridden and non-overridden constructor

Virtual constructors allow for polymorphic instantiation of objects. The classic example of this is Delphi's .dfm streaming mechanism.

The code that reads .dfm files and instantiates forms does not know at compile time which classes to use. The decision is postponed until runtime when it can be made correctly, i.e. when the .dfm file is read. Moreover, you can get the .dfm file mechanism to create custom components that are not part of the VCL and so this .dfm mechanism must be capable of correctly instantiating classes that are not part of the VCL.

The constructor for TComponent is declared like this:

constructor Create(AOwner: TComponent); virtual;

For a component to take part in this mechanism it must declare its constructor with the override directive.

The other key to the process is class references. For example

type
  TComponentClass = class of TComponent;

The code that creates components when reading .dfm files, roughly, looks like this:

var
  ComponentClass: TComponentClass;
  Component, Owner: TComponent;
....
ComponentClass = FindComponentClass(ReadComponentClassName);
Component := ComponentClass.Create(Owner);

Now, if the mechanism did not use virtual constructors then the constructor that would be called would be TComponent.Create. And so your constructor, TMyLabel.Create would never be called.

This is why you must include the override directive on your constructors when deriving from TComponent.