天天看點

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

繼續閱讀