假设我们有一个类层次结构。在底部我们有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:我在谈论与编译器无关的解决方案
答案 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
至少有一个虚拟成员函数的情况。无论如何,它应该通过基指针操作从它派生的类型,因此它应该有一个虚拟析构函数。