RTTI介绍
說明:部分內容來自<<程序員面試寶典>>和RTTI百度百科。
RTTI(run type identification):通過運行時類型信息程序能夠使用基類的指針或引用來檢查這些指針或引用所指的對象的實際派生類型。有些讀者認為設計類時使用虛函數就已經足夠了,可是虛函數本身有局限性,當涉及類別階層時,需要判斷某個對象所屬的類別,而因為類別設計中大量使用虛函數,所以使得這一工作難以實現,但又極其重要,于是使用RTTI的typeid運算符能使程序員確定對象的動態類型。
?
typeid操作符:返回指針和引用所指的實際類型
dynamic_cast操作符:將基類類型的指針或引用安全轉換為派生類型的指針或引用。(一個實際指向子類對象的指針被轉換成了父類指針,然后再用dynamic_cast轉換回來,一定會成,而一個實際指向父類對象的指針,被dynamic_cast轉換為子類指針,一定會失敗。成功返回1,失敗返回0)
?
#include<iostream> using namespace std;class base { public:virtual void funcA(){cout<<"base"<<endl;} };class derived:public base { public:virtual void funcB(){cout<<"derived"<<endl;} };void funC(base *p) {derived *dp=dynamic_cast<derived *>(p);//p是要轉換的指針,將指針p的類型轉換為(derived *)類型if(dp!=NULL)dp->funcB();elsep->funcA(); }void funcD(base *p) {derived *dp=NULL;if(typeid(*p)==typeid(derived))//如果p是指針,typeid(*p)返回p所指派生類類型,typeid(p)返回基類類型{dp=static_cast<derived *>(p);dp->funcB();} elsep->funcA();}int main() {base *cp=new derived;cout<<typeid(cp).name()<<endl;//打印cp類型名cout<<typeid(cp).name()<<endl;funcD(cp);funcC(cp);base *p=new base;funcC(dp);funcD(dp);return 0; }打印:
class base *
class base *
derived
derived?
base
base
?
dynamic_cast和static_cast區別:
static_cast是c的強制轉換,有一定的冒險性(信息丟失,內存越界)。
dynamic_cast是嘗試性的轉換,具有類型檢查功能。轉換成功返回新類型的合法指針,轉換失敗返回空指針。比較安全。
當我們能確定轉換是安全的時候用static_cast更快一些。
?
?
?
總結
- 上一篇: 类会默认产生的成员函数
- 下一篇: 剖析递归求二叉树高