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