天天看点

C++运行时类型识别(RTTI)

C++运行时类型识别(RTTI)

运行时类型识别RTTI(即Run-Time Type Identification).

主要通过typeid和dynamic_cast来实现

typeid操作符

  • type_id返回一个type_info对象的引用
  • 如果想通过基类的指针获得派生类的数据类型,基类必须带有虚函数
  • 只能够获取对象的实际类型

type_info实现如下:

class type_info
{
public:
        const char* name() const;//typeid调用此成员
        bool operator ==(const type_info& rhs) const;//对“==”运算符进行重载
        .......
}

           

应用如下:

typeid(* obj).name();  //打印出指针obj指向的实际的对象类型
if(typeid(* obj)==typeid(Bird));  //判断obj是否是Bird类型
           

也可以判断普通的数据类型:

int i=0;
std::cout<<typeid(i).name()<<std::endl;
           

dynamic_cast

如下:

  • .只能应用于指针和引用的转换
  • 要转换的类型中必须包含虚函数
  • 转换成功则返回子类地址,失败则返回NULL

下面展示展示一个实例:

//RTTI运行时类型识别

#include<iostream>
#include<string>
using namespace std;

class Flyable
{
public:
	virtual void takeoff() = 0;
	virtual void land() = 0;
};

class Plane :public Flyable
{
public:
	virtual void takeoff()
	{
		cout << "Plane--takeoff\n";
	}
	virtual void land()
	{
		cout << "Plane--land\n";
	}
	void carry()
	{
		cout << "Plane--carry\n";
	}
};

class Bird :public Flyable
{
public:
	virtual void takeoff()
	{
		cout << "Bird--takeoff\n";
	}
	virtual void land()
	{
		cout << "Bird--land\n";
	}
	void birdcall()
	{
		cout << "Bird--call\n";
	}
};

//定义一个全局函数
void dosomething(Flyable *obj)
{
	cout << typeid(*obj).name() << endl;//打印出指针obj指向的实际的对象类型
	obj->takeoff();
	if (typeid(*obj) == typeid(Bird))
	{
		Bird *bird = dynamic_cast<Bird *>(obj);
		bird->birdcall();
	}
	if (typeid(*obj) == typeid(Plane))
	{
		Plane *plane = dynamic_cast<Plane *>(obj);
		plane->carry();
	}
	obj->land(); 
}

int main(void)
{
	Bird b;
	dosomething(&b);
	Plane p;
	dosomething(&p);

	system("pause");
	return 0;
}
           

继续阅读