Я искал удобный способ сделать это в течение нескольких дней.
Вот как я это сделал наконец. Решение прагматично, быстро компилируется, переносимо и работает без RTTI .
Однако он использует #define, которого C ++ часто стараются избегать.
Может быть, кто-то может превратить этот код в тот, который использует шаблоны, которые мне также были бы интересны.
По сути, указатель на статический метод используется для сравнения с указателем, возвращаемым «другим» объектом в «static bool IsTypeOf (_TypeCheckBase & other)», чтобы обеспечить проверку типа.
Кроме того, вы можете получить название объекта.
#define TYPE_CHECK_IMPL(T) \
static bool IsTypeOf(_TypeCheckBase& other) { \
return other.GetType() == (unsigned int)&IsTypeOf; } \
virtual unsigned int GetType() { \
return (unsigned int)&IsTypeOf; } \
public: virtual const string& GetTypeName() { \
static string typeName = #T; \
return typeName; }
#define TYPE_CHECK_DECL(T) \
typedef T _TypeCheckBase;\
TYPE_CHECK_IMPL(T)
class root
{
public:
TYPE_CHECK_DECL(root)
};
class A: public root
{
public:
TYPE_CHECK_IMPL(A)
};
class AA: public A
{
public:
TYPE_CHECK_IMPL(AA)
};
class B: public root
{
public:
TYPE_CHECK_IMPL(B)
};
Нет, вы можете сделать следующее:
inline void prn(std::string txt, bool val)
{
cout << txt << ": " << (val ? "true":"false") << endl;
}
#define CMP(foo,bar) prn(#foo "\tis type of " #bar " TypeName:\"" + bar.GetTypeName() + "\"", foo::IsTypeOf(bar));
int main(void)
{
A a; AA aa;
B b;
cout << endl;
CMP(A,a);
CMP(AA,a);
CMP(B,a);
CMP(A,aa);
CMP(AA,(*((A*)&aa)));
CMP(B,aa);
CMP(A,b);
CMP(AA,b);
CMP(B,b);
}
Основные методы, которые вы здесь используете:
bool Foo :: IsTypeOf (bar), где Foo является типом класса, а bar является объектом, производным прямо или косвенно от типа корневого класса.
string bar.GetTypeName ()