Michael
I ask your question, but since your source code does not compile, I think you will miss the point of your question; -)
My answer is a bit of detailed information about what Mason tried to explain in his second answer.
The problem is that your question shows that you have a "class reference" (for example, TClass or TComponentClass) that refers to a base class with a virtual constructor. However, TClass does not (TClass refers to a class that has a non-virtual constructor), but TComponentClass does.
You see the difference when parsing a call to a constructor using a class reference. When you call a virtual constructor through a class reference, the code is slightly different from when you call a non-virtual constructor:
- virtual constructor call has indirect binding
- a call to a non-virtual constructor makes a direct call
This showdown shows what I mean:
TestingForVirtualConstructor.dpr.37: ComponentClassReference := TMyComponentClass; 00416EEC A1706D4100 mov eax,[$00416d70] TestingForVirtualConstructor.dpr.38: Instance := ComponentClassReference.Create(nil); // virtual constructor 00416EF1 33C9 xor ecx,ecx 00416EF3 B201 mov dl,$01 00416EF5 FF502C call dword ptr [eax+$2c] TestingForVirtualConstructor.dpr.39: Instance.Free; 00416EF8 E8CFCDFEFF call TObject.Free TestingForVirtualConstructor.dpr.41: ClassReference := TMyClass; 00416EFD A1946E4100 mov eax,[$00416e94] TestingForVirtualConstructor.dpr.42: Instance := ClassReference.Create(); // non-virtual constructor 00416F02 B201 mov dl,$01 00416F04 E893CDFEFF call TObject.Create TestingForVirtualConstructor.dpr.43: Instance.Free; 00416F09 E8BECDFEFF call TObject.Free
So, when you have a variable such as a reference to a class for which the constructor is virtual, and you call this constructor through this variable, you are sure that the actual class in this variable will have a virtual constructor.
You cannot determine on which particular class this constructor is implemented (well, not without additional debugging information, for example, from .DCU, .MAP, .JDBG or other sources).
Here is an example of the code that compiles:
program TestingForVirtualConstructor; {$APPTYPE CONSOLE} uses Classes, SysUtils; type TMyComponentClass = class(TComponent) MyStrings: TStrings; constructor Create(Owner: TComponent); override; end; constructor TMyComponentClass.Create(Owner: TComponent); begin inherited; end; type TMyClass = class(TObject) MyStrings: TStrings; constructor Create(); end; constructor TMyClass.Create(); begin inherited; end; procedure Test; var // TComponentClass has a virtual constructor ComponentClassReference: TComponentClass; ClassReference: TClass; Instance: TObject; begin ComponentClassReference := TMyComponentClass; Instance := ComponentClassReference.Create(nil); // virtual constructor Instance.Free; ClassReference := TMyClass; Instance := ClassReference.Create(); // non-virtual constructor Instance.Free; end; begin try Test; except on E: Exception do Writeln(E.Classname, ': ', E.Message); end; end.
To return to the original question: When a class reference refers to a base class that has a virtual constructor, you are sure that you will always call the virtual constructor using an indirect direction. When a class reference refers to a base class that has a non-virtual constructor, you are sure that you always call a non-virtual constructor using a direct call.
Hope this sheds some light on your question.
- Jeroen