C++通过以下两个运算符进行运行时类型识别:
1. typeid 查询类型的信息
在使用typeid前需要包含typeinfo头文件。
#include <typeinfo>
当typeid查询多态类型表达式时,将会有虚表查找的开销,查询其他表达式在编译前即完成。
可以通过typeinfo::name()函数获取类型名:
class Base { public: virtual void print() { cout << "Base:print()" << endl; } }; class A : virtual public Base { public: virtual void print() { cout << "A:print()" << endl; } }; int main() { Base *p = new A(); cout << typeid(3.14).name() << endl; cout << typeid(p).name << endl; cout << typeid(*p).name << endl; return 0; }
也可以通过typeid判断类型是否相同,但不能保证同一个类型都指向一个typeinfo对象,所以typeid(A) == typeid(B)可能出现错误。
同一类型获取的typeinfo对象hash_code()和type_index()一定是相同的。
typeid(A) == typeid(B) //不保证正确 typeid(A).hash_code() == typeid().hash_code(B) //保证正确 typeid(A).type_index() == typeid().type_index(B) //保证正确
2. dynamic_cast 将基类类型的指针或引用安全的转换为派生类型的指针或引用。
有时候指针并不单单代表一个地址,也有类型和大小的引申含义。使用多态特性时,错误的类型转换可能造成内存越界。
dynamic_cast运算符用于检测类型转换是否有效。
Base* b1 = new Base; if(Derived* d = dynamic_cast<Derived*>(b1)) { std::cout << "downcast from b1 to d successful "; d->name(); // 可以安全调用 }