Если вы не хотите использовать RTTI на всех (в том числе dynamic_cast
), вы можете моделировать его поведение, как Qt делает это с qgraphicsitem_cast
Outline:
class Base {
public:
enum { Type = 0 };
virtual int type() { return Type; }
};
class Derived : public Base {
public:
enum { Type = 1 };
int type() { return Type; }
};
template<typename T>
inline T myobject_cast(Base *b) {
if (b) {
// Requires C++11
if (int(std::remove_pointer<T>::type::Type) == b->type()) {
return static_cast<T>(b);
}
/* Pre C++11 (might be UB, but works on many compilers, OpenSource and Commercial)
if (int(static_cast<T>(0)->Type) == b->type()) {
return static_cast<T>(b);
}
*/
}
return NULL;
}
// use:
Base *b = new Base;
Base *d = new Derived;
Derived *o1 = myobject_cast<Derived*> (b); // NULL
Derived *o2 = myobject_cast<Derived*> (d); // d
Каждый класс требует уникальный Type
участник для этого, чтобы работать.
Помните, что это не будет работать с «промежуточными» классами в иерархии. Только фактический, наиболее производный тип может быть отлит (например, DerivedDerived
не может быть отлит до Derived
, или Base
, если на то пошло).
Вы также можете найти перегрузку Const удобно:
template<typename T> inline T myobject_cast(const Base *b)
{ return (b && int(static_cast<T>(0)->Type) == b->type()) ? static_cast<T>(p) : 0; }
const Base *cb = new Derived;
const Derived *co = myobject_cast<const Derived *>(cb);
Вы упомянули, вы не знаете, какой индекс соответствует какому классу, но все-таки нужно вызвать 'func2()'. Таким образом, вы не можете гарантировать, что 'func2()' будет вызываться для объектов 'Derived'. Какой результат вы ожидаете от вызова 'func2()' для объектов 'Base'? – alexeykuzmin0
Возможно, вы захотите прочитать о [object] (https://en.wikipedia.org/wiki/Object_slicing) [slicing] (http://stackoverflow.com/questions/274626/what-is-object-slicing). –
@ alexeykuzmin0 Я бы хотел узнать тип класса, может быть? Я открыт для любых других решений :) – mkmostafa