2010-06-02 89 views
2

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

#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 
} 

制作方法虚拟,让派生类做这似乎是一个好主意,因为我有同类型层次结构中的很多类。 还是有人知道任何其他/更好的方式来做同样的事情吗?请建议。 (a)应检测输入对象类型(a)是否是类型层次结构中当前对象(b)的祖先。

+0

虽然我不确定这可以b如果做得好,我也不知道这*如何可能会有用。出于好奇,你为什么想要实现这一目标? – ereOn 2010-06-02 11:29:57

+0

有关示例,请参阅Neil答案的评论。 – Elroy 2010-06-02 11:33:39

+0

例如。 C派生自B派生自A,X派生自A.在某些情况下,我可能需要验证基类指针(A *)指向的对象类型应该是类型B,而不是类型X,失败我会抛出一个错误。 – Elroy 2010-06-02 11:37:40

回答

2

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

的语法错误代码:

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

是因为typeid的是不是一个类型 - 你根本无法将它用这样的dynamic_cast类型。

如果作为纳文提出要看看实例属于一个子层次,使用方法:

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 
+0

请注意,'B类'和'C类'是从'A类'派生的。我认为OP的意图是找出传递的对象是否属于这个子层次。 – Naveen 2010-06-02 09:55:50

+0

我很抱歉没有让自己真正清楚。例如。 X派生自P,Y派生自Q,其中P和Q派生自A.因此,X属于P和A,Y属于Q和A,但X不属于Q.我需要这种行为。 – Elroy 2010-06-02 11:20:08

+0

我不确定是否有这种检测的名称,但它看起来像检查祖先。 – Elroy 2010-06-02 11:22:13

2

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

+0

我在每个类中添加了一个虚拟析构函数。但它仍然显示语法错误。有任何想法吗? – Elroy 2010-06-02 09:51:29

+0

是的,请参阅Neil Butterworth的答案。 – sharptooth 2010-06-02 10:06:27