5

have simple object hierarchy like below

TLiveThing=class
protected
 FTest:string;
 constructor Create(whereLive:string);overload;virtual;
 constructor Create(haveBone:Boolean);overload;virtual;
end;

THuman=class(TLiveThing)
public
 constructor Create(whereLive:string);overload;override;
 constructor Create(age:integer);overload;
end;

in theoretically, if I instantiate THuman, I have 2 constructor, but in fact I have 5 constructor displayed by code insight, actually I want to see 3 constructor, - Create(whereLive:String), overriden - Create(age:integer) - Create(haveBone:integer)

human:=THuman.Create(       <=====in there I have 5 suggestion constructor

why I have this strange behaviour? how to fix it, because it so anoying, I cant always check my class that I need to instantiate, and if I instantiate like below

human:=THuman.Create(); <===== it doesnt give me error

how I completely hide my anchestor constructor? , because if I instatiate like above, completely give me a wrong object

UPDATE: and also I can see default Create without parameter from TObject too

navirius
  • 209
  • 1
  • 7
  • 14
  • You have too many virtual constructors. You need to have only one of those. – David Heffernan May 25 '13 at 04:46
  • 1
    Are you sure you need any virtual constructors? Do you ever actually instantiate any of these classes without knowing the type at compile time? If not, then you don't need virtual constructors. – Rob Kennedy May 25 '13 at 04:59
  • It's hard to advise you here, because we don't know what's driving you to have so many overloaded and virtual constructors. On the face of it your entire design smells. My instincts are that fixing the design will solve the problems. Attempting to hide constructors is akin to putting a clothes peg on your nose. The design still reeks, you just can't smell it any more. – David Heffernan May 25 '13 at 05:32
  • oke, I update my question to make clear my point, because actually in my code, both constructor have completely different parameter and sometime I need override both of constructor from base class, and sometimes I just use constructor from base class. Of course I can rename another constructor to CreateByWhereLive or something else different to work around with this problem, and I can make it work correctly, but if I use "Create", I can't understand why it have behavior like that... – navirius May 25 '13 at 05:57
  • Your update doesn't change anything. You didn't address any of the points that Rob and I raised. – David Heffernan May 25 '13 at 06:12
  • in my case, yes I need all that overload and virtual constructor, I code in C# too, but in c#, I can instantiate object without confuse about default constructor (parameterless constructor), if my class doesnt have default constructor, I will make it private, then I can not instantiate with that constructor...just for comparison, so in delphi, I search how to hide ancestor constructor if my derived object doesnt have that constructor – navirius May 25 '13 at 06:42
  • possible duplicate of [How to hide the inherited TObject constructor while the class has overloaded ones?](http://stackoverflow.com/questions/14003153/how-to-hide-the-inherited-tobject-constructor-while-the-class-has-overloaded-one) – David Heffernan May 25 '13 at 06:57
  • 4
    *I need all that overload and virtual constructor.* I beg to differ. You should not have more than one virtual constructor. If you do, your design is wrong. – David Heffernan May 25 '13 at 06:58
  • possible duplicate of [Delphi: How to hide ancestor constructors?](http://stackoverflow.com/questions/3874330/delphi-how-to-hide-ancestor-constructors) – bummi May 25 '13 at 08:06
  • oke, I understand and use that method for hide default constructor TObject, but I want, 2 constructor from base class, that can be overriden or not by derived object, if class override two constructor from base class, so if I instantiate I only have 2 constructor, if derived class have one original constructor and one overriden constructor from base class, I expected I have 3 constructor if I instantiate object, 1 from base class, 2 from derived class( original one and overriden constructor one), how to achieve that? – navirius May 26 '13 at 03:04

1 Answers1

1

Without putting focus on your bad constructor implementation,

your problem is that both the ancestor and the child class are defined in the same unit, therefor the standard definition of Private/Protected does not apply here.

If you want to prevent the ancestor constructor (which you are overriding in the child class) from showing up as a code parameter when instantiating an object of that derrived class then simply make it a member of the strict protected or strict private section.

With your example :

TLiveThing=class
strict protected
 constructor Create(whereLive:string); virtual;
end;

THuman=class(TLiveThing)
public
 constructor Create(whereLive:string); overload; override;
 constructor Create(age:integer); overload;
end;

This will prevent the ancestor constructor Create(whereLive:string) from showing up as a parameter when you are creating an instance of your child class.

As pointed out by David, this has nothing to do with hiding the default Create constructor, it's only viable for hiding your custom constructors.

Peter
  • 2,977
  • 1
  • 17
  • 29
  • That won't help at all. The parameterless `TObject.Create` is made visible by the introduction of an overloaded `Create`. See the duplicate. – David Heffernan May 25 '13 at 06:57
  • Yes, but also he said that he wants to hide the ancestor constructor Create(whereLive:string) and this will at least help him hide that. – Peter May 25 '13 at 07:02
  • so, thats mean, in delphi, if I have 2 virtual constructor on base class, then derived class have 1 constructor and 1 overriden from base, then when I instantiate object from derived class, I can have 4 constructor, include the overriden one ( I got that experience from my code at my question) thats bug or just like that? (because I dont get any behavior like that on c#) – navirius May 26 '13 at 02:24
  • because, actually I dont want hide some constructor with strict private, I just want, that constructor is overriden by derived class, so if I instantiate object, I can see overriden constructor just constructor from derived object, my experience in delphi, code insight give me suggestion constructor from base class and constructor from derived class, though I already override that constructor – navirius May 26 '13 at 03:09
  • @navirius , the strict word has no influence on the override directive of a method, the result will be the same. I think you got confused by the word hidden in my answer. The ancestor virtual constructor which you decided to override in your derived class will still be overriden, the word strict just means that if both Parent and Child class are defined in the same unit, it will ommit the confusion that you are now experiencing when instantiating an object. You could achieve the same result by writing Ancestor class in Unit1 and Child class in Unit2. I will update answer, hope you accept it. – Peter May 27 '13 at 13:02