代码之家  ›  专栏  ›  技术社区  ›  Ash Machine

通过检测当前“对象”类型在C++中进行类型转换

  •  2
  • Ash Machine  · 技术社区  · 6 年前

    我的问题与C++中的RTTI有关,我在这里试图检查一个对象是否属于另一个对象的类型层次结构。BelongsTo()方法检查这一点。

    #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)的祖先。

    2 回复  |  直到 15 年前
        1
  •  2
  •   anon anon    15 年前

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

    代码中的语法错误:

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

    是因为typeid不是一个类型-你不能用它作为一个动态类型。

    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
    
        2
  •  2
  •   sharptooth    15 年前

    为了让RTTI工作 class X 需要至少一个虚拟成员函数(虚拟析构函数也计算在内)。如果没有虚拟成员函数,类将不会有编译器生成的vtable,因此在调用 typeid 后者不会像你期望的那样起作用。