Эти вещи, безусловно, были бы полезны, а именно - заставить все объекты в иерархии классов предоставлять фабричный метод вместо обычного конструктора. Фабрики очень полезны для того, чтобы гарантировать, что вы никогда не создадите недопустимые объекты, что является гарантией того, что вы не сможете применить их так же хорошо, как обычные конструкторы.
Чтобы построить «виртуальную статику», нужно вручную собрать собственную «статическую виртуальную таблицу» во все объекты, которые в ней нуждаются. Обычные виртуальные функции-члены работают, потому что компилятор создает секретную таблицу указателей функций, называемую VTABLE, во все экземпляры вашего класса. При создании объекта «T» указатели на функции в этой таблице назначаются адресам первого предка, предоставляющего этот API. Затем переопределение функции просто заменяет исходный указатель в объекте, который вы получаете из «нового», на новый, предоставленный в производном классе. Конечно, компилятор и среда выполнения обрабатывают все это для нас.
Но, в очень старые времена, до современного c ++ (так мне сказали), вам пришлось настроить это волшебство самостоятельно. И это все еще касается виртуальной статики. Хорошая новость заключается в том, что таблица, которую вы создаете для них вручную, на самом деле проще, чем «обычная», ее записи ни в коем случае не дороже, включая пространство и производительность, чем записи для функций-членов. Просто определите базовый класс с набором функциональных указателей EXPLICIT (статическая таблица) для API, которые вы хотите поддерживать:
template<typename T>
class VirtualStaticVtable {
private:
typedef T (*StaticFactory)(KnownInputParameters params);
StaticFactory factoryAPI; // The 1 and only entry in my static v-table
protected:
VirtualStaticVtable(StaticFactory factoryApi) : factoryAPI(factoryApi) {}
virtual ~VirtualStaticVtable() {}
};
Теперь каждый объект, который должен поддерживать статический метод фабрики, может быть получен из этого класса. Они спокойно передают свои собственные фабрики своему конструктору, и он только добавляет 1 указатель к размерам результирующих объектов (как обычная запись VTable).
Струсуп и Ко мог бы добавить этот идиоматический паттерн к основному языку, если бы захотел. Это даже не будет так сложно. Каждый объект в таком «C +++» просто имел бы 2 vtables вместо 1-1 для функций-членов, принимающих this в качестве аргумента, и 1 для обычных указателей на функции. Однако до того дня мы застряли с ручными таблицами vtable, как это было со старыми программистами на C до появления c ++.