天天看点

C++学习笔记之运行时刻类型识别RTTI

运行时刻类型识别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不仅能发现准确的类型,并且能在多层的继承层次中将类型转换到中间层类型。

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;
}
           

继续阅读