В C ++ предположим следующую иерархию классов:
class BaseClass { };
class ChildClass : public BaseClass { };
Далее предположим, что фабричные классы для этих двух классов имеют общий базовый шаблонный шаблон:
template<typename T>
class Factory {
public:
virtual T* create() = 0;
};
class BaseClassFactory : public Factory<BaseClass> {
public:
virtual BaseClass* create() {
return new BaseClass(&m_field);
}
private:
SomeClass m_field;
};
class ChildClassFactory : public Factory<ChildClass> {
public:
virtual ChildClass* create() {
return new ChildClass(&m_field);
}
private:
SomeOtherClass m_field; // Different class than SomeClass
};
Обратите внимание, чтоВнутренняя структура ChildClassFactory
и BaseClassFactory
отличается из-за их разных полей.
Теперь, если есть экземпляр ChildClassFactory
(или Factory<ChildClass>
), могу ли я безопасно привести его к Factory<BaseClass>
(через reinterpret_cast
)?
Factory<ChildClass>* childFactory = new ChildClassFactory();
// static_cast doesn't work - need to use reinterpret_cast
Factory<BaseClass>* baseFactory = reinterpret_cast<Factory<BaseClass>*>(childFactory);
// Does this work correctly? (i.e. is "cls" of type "ChildClass"?)
BaseClass* cls = baseFactory->create();
Я знаю, что вы не всегда можете кастовать шаблонные классы таким образом, но в этом особом случае приведение должно быть безопасным, не так ли?
Я протестировал его с Visual C ++ 2010, и он работает.Теперь у меня вопрос: переносимо ли это на другие компиляторы?
Обновление: Поскольку произошла путаница, позвольте мне еще кое-что прояснить (что должно быть) в моем примере:
ChildClass
- это дочерний класс BaseClass
- Пользователь
Factory<BaseClass>
не знает, какой дочерний класс BaseClass
будет создан.Все, что он знает, это то, что BaseClass
создано. Factory<T>
не имеет собственных полей (кроме vtable). Factory::create()
равно virtual