2

我的问题与 C++ 中的 RTTI 有关,我试图检查一个对象是否属于另一个对象的类型层次结构。BelongsTo() 方法检查这一点。我尝试使用 typeid,但它会引发错误,我不确定如何找到在运行时转换为的目标类型。

#include <iostream>
#include <typeinfo>

class X
{
    public:
        //  Checks if the input type belongs to the type heirarchy of input object type
        bool BelongsTo(X* p_a)
        {
            //  I'm trying to check if the current (this) type belongs to the same type 
            //  hierarchy as the input type
            return dynamic_cast<typeid(*p_a)*>(this) != NULL;   //  error C2059: syntax error 'typeid'
        }
};

class A : public X
{
};

class B : public A
{
};

class C : public A
{
};

int main()
{
    X* a = new A();
    X* b = new B();
    X* c = new C();
    bool test1 = b->BelongsTo(a);   // should return true
    bool test2 = b->BelongsTo(c);   // should return false
    bool test3 = c->BelongsTo(a);   // should return true
}

使方法虚拟并让派生类这样做似乎是个坏主意,因为我在同一类型层次结构中有很多类。或者有人知道做同样事情的任何其他/更好的方法吗?请建议。

更新:b.BelongsTo(a) 应该检测输入对象类型 (a) 是否是类型层次结构中当前对象 (b) 的祖先。

4

2 回答 2

2

为了使 RTTI 工作class X,至少需要一个虚拟成员函数(虚拟析构函数也很重要)。如果没有虚拟成员函数,该类将没有编译器生成的 vtable,因此当您调用typeid后者时,它将无法按预期工作。

于 2010-06-02T09:39:26.217 回答
2

这没有任何意义 - 您可以调用函数这一事实意味着参数属于 X 层次结构,因为那是参数的类型。动态转换旨在找出已知层次结构中的实际类型。

代码中的语法错误:

return dynamic_cast<typeid(*p_a)*>(this) != NULL;  

是因为 typeid 不是类型 - 您根本不能将它用作具有 dynamic_cast 这样的类型。

如果像 Naveen 建议的那样,您想确定一个实例是否属于子层次结构,请使用:

if ( dynamic_cast <A*>( some_x_ptr ) ) {

    // yes, belongs to A sub-hierarchy
}

编辑:你有:

A <- P <- X
A <- Q <- Y

然后:

A * a = new X;

dynamic_cast <P *>( a );   // not null
dynamic_cast <Q *>( a );   // null
于 2010-06-02T09:42:36.987 回答