1

I was reading this article because I wanted to understand the usefulness of class of [ClassName] and I have seen that they declare a virtual constructor. So I have made a test that you can see here:

enter image description here

I understand (from that article) that virtual constructors are useful when I don't know at compile-time the class I want to construct and I can use the class of. In the code I have shown above, what is the difference?

If I declared TFirst constructor as virtual without overriding TSecond I'll get the warning of course ad I can remove that with a reintroduce or override. But isn't the constructor automatically overridden (look at the code on the left)? I think that they are equivalet.

Raffaele Rossi
  • 2,997
  • 4
  • 31
  • 62
  • 2
    **Please** don't use screenshots for code! You can paste syntax highlighted code - use the `{}` button or look [here](https://stackoverflow.com/help/formatting). – Uli Gerhardt Jul 10 '17 at 11:41
  • They aren't equivalent. You'll observe a difference if you attempt to create an instance via a class reference. I'm pretty sure the documentation covers this. Does it? – David Heffernan Jul 10 '17 at 11:58
  • Documentation: http://docwiki.embarcadero.com/RADStudio/en/Methods_(Delphi)#Constructors http://docwiki.embarcadero.com/RADStudio/en/Class_References always prudent to read documentation – David Heffernan Jul 10 '17 at 12:34
  • @RaffaeleRossi as David pointed out it's on the doc. To directly answer your question if the two codes are equal or not see this: "When invoked through a class-type identifier, a constructor declared virtual is equivalent to a static constructor. When combined with class-reference types, however, virtual constructors allow polymorphic construction of objects" – Alberto Miola Jul 25 '17 at 13:44

1 Answers1

4

Execute this code with both variants and you will see the difference.

type
  TFirstClass = class of TFirst;

constructor TFirst.Create;
begin
  Writeln('TFirst.Create');
end;

constructor TSecond.Create;
begin
  Writeln('TSecond.Create');
end;

var
  firstClass: TFirstClass;
  first: TFirst;
begin
  firstClass := TSecond;
  first := firstClass.Create;
end.
Stefan Glienke
  • 20,860
  • 2
  • 48
  • 102
  • Ok thank you Stefan, but actually my question was: is there any difference if I use vritual/override (in the constructor of father/child) or not? In general I mean – Raffaele Rossi Jul 10 '17 at 11:46
  • 3
    I think executing the example code shows the difference pretty clearly – Stefan Glienke Jul 10 '17 at 12:00
  • 1
    Use the code shown in this answer as implementations for your given declarations, @Raffaele. In the nonvirtual case, you'll see only a message about `TFirst`, whereas in the virtual case, you'll see a message about `TSecond` instead. (But beware: In *both* cases, checking `first is TSecond` will return `True`!) – Rob Kennedy Jul 10 '17 at 12:00
  • Ok I think I got it. In code above is possible to see 'TSecond.Create' with the virtual/override because I am going to redefine (with override in fact) the constructor. Without virtual/override I am not giving a new definition of TSecond.Create (in fact I have NO override) and so I see TFirst.Create. I guess that my idea is correct – Raffaele Rossi Jul 10 '17 at 12:18
  • 2
    @Raffaele: Without the virtual constructor, the constructor that is declared for the type (`TFirstClass` --> `class of TFirst`) is used. But with a virtual constructor, you get the constructor of the ***actual***, not of the ***declared*** class, and the actual class is `TSecond`. That is the same as for virtual and non-virtual normal methods. – Rudy Velthuis Jul 10 '17 at 12:31
  • 1
    Instead of saying "execute this and see the difference" you could have actually posted the result and explained the difference. – spiderface Jun 07 '21 at 14:18