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

use*_*475 17 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
Run Code Online (Sandbox Code Playgroud)

有什么方法除了手动实现字符串字段或这样的虚拟get函数?

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

Che*_*Alf 29

确保基类至少有一个虚方法,包含<typeinfo>并使用当前代码,只需另外解除引用typeid(*b).name().


在传递中,请注意,typeid调用是C++中的一个位置,您可以在其中取消引用具有明确定义的行为的nullpointer,这意味着它可以抛出异常:

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

  • 将析构函数作为"至少一个虚方法"是个好主意 (5认同)

Rei*_*ica 12

如果你想要做的就是找到b实际指向的Derived,只需使用dynamic_cast():

if (dynamic_cast<Derived*>(b)) { ... }
Run Code Online (Sandbox Code Playgroud)

dynamic_cast如果指向的对象的实际运行时类型b不是Derived(或派生自的类Derived),则返回空指针.与name()成员不同std::type_info,这是编译器不变的.

请注意,这仅Base在至少具有一个虚拟成员函数时才有效.无论如何,它应该通过基指针操作从它派生的类型,因此它应该有一个虚拟析构函数.