运行时刻类型识别RTTI
仅当有一个指针或引用指向基类型时,利用运行时类型识别(RTTI)可以找到一个对象的动态类型。
1. 运行时类型转换 dynamic_cast
转换类型:
上行转换up-casting (把派生类的指针或引用转换成基类的指针或者引用表示)
下行转换down-casting(把基类指针或引用转换成子类的指针或者引用)
dynamic_cast 要求转换的对象是多态的,这要求该类对象必须至少有一个虚函数。
dynamic_cast在程序运行时使用虚函数表,所以比其它风格的类型转换代价更高。
运行时类型转换可以查证所尝试进行的转换是否正确:
1. 如果对象是指针可以通过判定返回是否为NULL来检测转换是否成功
2. 如果对象是引用则需要通过捕获bad_cast异常。
2. typeid操作符
typeid返回type_info类对象信息。
typeid实现RTTI功能,操作的对象必须是类类型(带有虚表函数),而不能是一个指针。
把typeid应用到空指针或表达式会引起一个bad_typeid的异常被抛出。
2.1 类型转换到中间层次类型
dynamic_cast不仅能发现准确的类型,并且能在多层的继承层次中将类型转换到中间层类型。
仅当有一个指针或引用指向基类型时,利用运行时类型识别(RTTI)可以找到一个对象的动态类型。
1. 运行时类型转换 dynamic_cast
转换类型:
上行转换up-casting (把派生类的指针或引用转换成基类的指针或者引用表示)
下行转换down-casting(把基类指针或引用转换成子类的指针或者引用)
dynamic_cast 要求转换的对象是多态的,这要求该类对象必须至少有一个虚函数。
dynamic_cast在程序运行时使用虚函数表,所以比其它风格的类型转换代价更高。
运行时类型转换可以查证所尝试进行的转换是否正确:
1. 如果对象是指针可以通过判定返回是否为NULL来检测转换是否成功
2. 如果对象是引用则需要通过捕获bad_cast异常。
2. typeid操作符
typeid返回type_info类对象信息。
typeid实现RTTI功能,操作的对象必须是类类型(带有虚表函数),而不能是一个指针。
把typeid应用到空指针或表达式会引起一个bad_typeid的异常被抛出。
2.1 类型转换到中间层次类型
dynamic_cast不仅能发现准确的类型,并且能在多层的继承层次中将类型转换到中间层类型。
typeid始终指向产生指向type_info型对象的引用,它描述改类型的动态类型。typeid不能给出中间层对象的类型信息。
#include <iostream>
using namespace std;
class B1{
public:
virtual ~B1(){}
};
class B2{
public:
virtual ~B2(){}
};
class M1:public B1,public B2{};
class M2:public M1{};
int main(int argc, char *argv[])
{
M2 mm2;
B2 *b2 = &mm2;
cout<<typeid(*b2).name()<<endl;
M2 *m2 = dynamic_cast<M2 *>(b2);
M1 *m1 = dynamic_cast<M1 *>(b2);
B1 *b1 = dynamic_cast<B1 *>(b2);
cout<<typeid(*b1).name()<<endl;
cout<<typeid(*b2).name()<<endl;
cout<<typeid(*m1).name()<<endl;
cout<<typeid(*m2).name()<<endl;
while(1);
return 0;
}