|
Виртуальные конструкторы актуальны только тогда, когда мы можем создать ссылку на класс. В Дельфи это синтаксически описывается так:
Type TMyClass_Ref = class of TMyClass;
Создав переменную типа TMyClass_Ref, я могу присвоить ей любой из типов, который есть потомок класса TMyClass, включая и сам TMyClass. Например,
Var MyClass_Ref : TMyClass_Ref;
Далее где-то могу сделать так:
MyClass_Ref := TMyClass;
или
MyClass_Ref := TMyClassChild;
где TMyClassСhild - некий класс-потомок от TMyClassСhild. После этого я могу эту переменную переслать кому-то еще (например, некоему классу, созданному третьим лицом). И этот кто-то еще уже создаст экземпляр этого класса (или не создаст, или создаст 50 экземпляров этого класса). Создать экземпляр, имея ссылку на клсаа, можно, например, так:
Var SomeClass : TMyClass;
SomeClass = MyClass_Ref.Create(param1, param2, ...);
где Create - виртуальный конструктор класса TMyClass и всех его потомков.
В Си++, к сожалению, ссылок на классы нет. По своей сущности ссылка на класс - это указатель на VMT класса.
По поводу шаблонов повторюсь: шаблоны это по сути своей расширенный препроцессор. Они хороши тогда, когда на этапе компиляции известно, какие классы будут создаваться. Здесь заметим, что если в шаблон включен класс целиком (классический пример - list), то порожденные от него на этапе компиляции классы ListClass1 и ListClass2, определенные соответственно как list(.Class1.) ListClass1 и list(.Class2.) ListClass2, то они будут несовместимыми, т.е. нельзя будет породить указатель на класс, которому мы могли бы присвоить как экземпляры типа ListClass1, так и экземпляры типа ListClass2 (с возможностью вызывать виртуальные методы этих классов).
Примечание: здесь использованы обозначения "(." - левая угловая скобка; ".)" - правая угловая скобка. (Просто угловые скобки сайт проглатывает и не отображает их содержимое, несправедливо полагая, что это html-тег).