C++ gcc 9.3.0 派生指针的 typeid 总是 return typeid(BaseClass*) 但 dynamic_cast<derived_ptr> 工作正常

C++ gcc 9.3.0 typeid of derived pointer always return typeid(BaseClass*) but dynamic_cast<derived_ptr> works fine

有几个类似的帖子,这里是我的最小案例代码:

bool useDerived=true;
BaseClass* maker;
if (useDerived) {
    maker = new DerivedClass();
}
else {
    maker = new BaseClass();
}
if (typeid(maker) == typeid(DerivedClass*)) {
    cerr << "is derived type\n";
}
else {
    cerr << "not derived type\n";
}
DerivedClass* x = dynamic_cast<DerivedClass*>(maker);
if (x == nullptr) {
    cerr << " cannot cast back to derived\n";
}
else {
    cerr << " cast to derived OK\n";
}

结果是:

not derived type
cast to derived OK

我是不是漏掉了什么?我包括 <typeinfo> header。会不会是编译器 version-specific 错误?

DerivedClass 派生自BaseClassDerivedClass 实现了BaseClass 的多个虚函数。使用 typeid 的想法基于 blog 部分:Typeid as faster dynamic_cast.

这里没有错误。

typeid() 在编译时计算。 BaseClass*DerivedClass* 是两种完全不同的指针类型,因此比较它们各自的 std::type_info 结构永远不会比较相等。

dynamic_cast 在运行时计算。将 BaseClass* 指针转换为 DerivedClass* 指针将调用 RTTI 查找以查找和 return 指向对象的 DerivedClass 部分的指针,BaseClass* 指针指着。如果对象不实现 DerivedClassdynamic_cast 将 return nullptr.

typeid 被静态计算 in this case。你应该取消引用,所以你会给它一个多态类型的 glvalue,而不是一些指针类型。

这一行:

if (typeid(maker) == typeid(DerivedClass*)) {

应该是:

if (typeid(*maker) == typeid(DerivedClass)) {