4

I created a class

  FormInfo = class (TComponent)
  private
    FLeftValue : Integer;
    FTopValue : Integer;
    FHeightValue : Integer;
    FWidthValue : Integer;
  public
    constructor Create(
      AOwner : TComponent;
      leftvalue : integer;
      topvalue : integer;
      heightvalue : integer;
      widthvalue : integer);
  protected
    procedure GetChildren(Proc: TGetChildProc; Root: TComponent); override;
    function  GetChildOwner: TComponent; override;
    //procedure SetParentComponent(Value : TComponent); override;
  published
    property LeftValue : Integer read FLeftValue write FLeftValue;
    property TopValue : Integer read FTopValue write FTopValue;
    property HeightValue : Integer read FHeightValue write FHeightValue;
    property WidthValue : Integer read FWidthValue write FWidthValue;
  end;

which is used further for form serialization. The Create method has the following implementation

constructor FormInfo.Create(AOwner: TComponent; leftvalue, topvalue, heightvalue,
  widthvalue: integer);
begin
  inherited Create(AOwner);

  FLeftValue := leftvalue;
  FTopValue := topvalue;
  FHeightValue := heightvalue;
  FWidthValue := widthvalue;
end;

As a result of assembly I receive warning

[dcc32 Warning] SerialForms.pas(17): W1010 Method 'Create' hides virtual method of base type 'TComponent'

What it is necessary to make to get rid of this warning without loss of functionality of application?

user1851132
  • 341
  • 1
  • 6
  • 15
  • 1
    See http://docwiki.embarcadero.com/RADStudio/XE3/en/W1010_Method_%27%25s%27_hides_virtual_method_of_base_type_%27%25s%27_%28Delphi%29 – ain Dec 19 '12 at 14:34
  • 2
    When your form is created from a .dfm file it calls the virtual constructor introduced in `TComponent`. Your constructor won't ever get called when the form comes in from .dfm. If your constructor created any objects, then you'd have problems. Your design is probably wrong. – David Heffernan Dec 19 '12 at 14:46
  • 2
    To hide inherited `TComponent` virtual ctor is a bad idea, if you want to have additional ctor use a different name like `CreatePos`. – kludg Dec 19 '12 at 14:59
  • 1
    @user You have asked quite a few questions now. Which is fine. But perhaps you could consider voting for good answers. – David Heffernan Dec 19 '12 at 15:40
  • BTW Do you know that in more recent Delphi versions you can do Ctrl-F1 on the error/warning/hint messages to get more info? Notably, the help on this error gives specific reasons and solutions – Jan Doggen Dec 21 '12 at 09:00

2 Answers2

8

Use the reintroduce reserved word to indicate the compiler you want to intentionally hide the base class constructor in your class:

TMyClass = class (TComponent)
public
  constructor Create(AOwner: TComponent; MyParam: Integer; Other: Boolean); reintroduce;

That way, no warning is shown.

That said, you have to re-think hiding the TComponent.Create constructor. It is a bad idea since the default TComponent.Constructor is called by Delphi to create your component instances at run-time when added to forms/data modules at design time.

TComponent makes the constructor virtual to allow you execute custom code during that process, but you have to stick with the Create firm passing you only the owner, and let the streaming mechanism to deal with the stored values for properties after the creation is complete.

Your component have to support being "unconfigured" if that's the case, or setup default values for it's properties in this universal constructor.

You can provide more constructors, with different names, to allow you create instances at run-time from code passing values for the different properties for your convenience.

jachguate
  • 16,976
  • 3
  • 57
  • 98
  • Reintroduce breaks polymorphism. Which means that you can no longer use meta classes (TxxxClass = class of Tyyy) to instantiate your TComponent descendant as its Create won't be called. See also: http://stackoverflow.com/questions/53806/reintroducing-functions-in-delphi – Marjan Venema Dec 19 '12 at 18:19
  • @Marjan You still can create instances using meta classes and the virtual constructor. IMHO, having the ability to hide a virtual constructor is just a tool you have at hand and may come to be useful at a times. I can't recall when I used it or if I did once. I'm not against it, but it looks like I don't use it also. – jachguate Dec 20 '12 at 00:27
  • Yes you can, but I really don't see the use of hiding something that you can access anyway. I prefer to make an explicitly named constructor ( ie `CreateWith`) for this sort of thing that calls the standard constructor first (without inherited). – Marjan Venema Dec 20 '12 at 07:57
2

It might be better - and more readable if you use a different name for your constructor, such as

constructor FormInfo.CreateWithSize(AOwner: TComponent; leftvalue, topvalue, heightvalue, widthvalue: integer);
Alister
  • 6,527
  • 4
  • 46
  • 70