18

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

Base* b = new Derived():

typeid(b).name(); // i want this to tell me that this is actually derived not base object

除了手动实现字符串字段或此类虚拟获取功能之外,还有其他方法吗?

PS:我说的是独立于编译器的解决方案

4

2 回答 2

32

确保基类至少有一个虚拟方法,包括<typeinfo>并使用你当前的代码,只是额外的取消引用,typeid(*b).name().


顺便说一句,请注意,typeid调用是 C++ 中的一个地方,您可以在其中取消引用具有明确定义行为的空指针,这意味着它可以引发异常:

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

于 2013-04-09T09:22:44.950 回答
16

如果您只想找到 ifb实际指向Derived,只需使用dynamic_cast()

if (dynamic_cast<Derived*>(b)) { ... }

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

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

于 2013-04-09T09:32:24.570 回答