如何在C ++中确定运行时的实际对象类型;

时间:2013-04-09 09:20:55

标签: c++ typeid typeinfo

假设我们有一个类层次结构。在底部我们有Base和顶部Derived。 如何确定对象类,即使它被转换为基类指针。

Base* b = new Derived():

typeid(b).name(); // i want this to tell me that this is actually derived not base object
除了手动实现字符串字段或者这样的虚拟get函数之外,还有什么方法吗?

PS:我在谈论与编译器无关的解决方案

2 个答案:

答案 0 :(得分:28)

确保基类至少有一个虚拟方法,包括<typeinfo>,并使用您当前的代码进行额外的解除引用typeid(*b).name()

<小时/> 顺便说一句,请注意typeid调用是C ++中的一个地方,您可以在其中取消引用具有明确定义的行为的nullpointer,这意味着它可以抛出异常:

  

C ++11§5.2.8/ 2
  “如果通过将一元*运算符应用于a来获得glvalue表达式   指针和指针是空指针值(4.10),typeid表达式抛出std::bad_typeid异常(18.7.3)。“

答案 1 :(得分:12)

如果您想要做的只是b实际上指向Derived,请使用dynamic_cast()

if (dynamic_cast<Derived*>(b)) { ... }
如果dynamic_cast指向的对象的实际运行时类型不是b(或从Derived派生的类),则

Derived返回空指针。与name()的{​​{1}}成员不同,这是编译器不变的。

请注意,这只适用于std::type_info至少有一个虚拟成员函数的情况。无论如何,它应该通过基指针操作从它派生的类型,因此它应该有一个虚拟析构函数。