日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

RTTI: dynamic_cast typeid

發(fā)布時間:2023/12/10 编程问答 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 RTTI: dynamic_cast typeid 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

dynamic_cast:將基類類型的指針向派生類指針安全轉換。多用于下行轉換。上行轉換時,和static_cast是一樣的。C++類型轉換看這里。而const_cast用來修改類型的const或volatile屬性。。。下面主要說多態(tài)下的RTTI:

使用條件:
  基類應有虛函數
  編譯器需啟用Runtime Type Information/Identification(RTTI),運行時類型信息。VS下在項目屬性頁下啟用,如下,選?: (VS2013測試:默認的留不選也能正常使用dynamic_cast)

結果:
  對指針進行dynamic_cast,失敗返回null,成功返回正常cast后的對象指針; //首選
  對引用進行dynamic_cast,失敗拋出一個異常std::bad_cast,成功返回正常cast后的對象引用。

用處:一般用在多態(tài)中,即基類的指針或引用指向派生類對象時,進行安全的向下轉換。
   多態(tài)的基本例子如下:

#include <iostream> using namespace std;class Base { public:virtual void vFoo(){cout << "Base::vFoo()" << endl;}virtual ~Base(){ } };class Derived : public Base { public: virtual void vFoo(){cout << "Derived::vFoo()" << endl;}void Other(){cout << "Derived::Other()" << endl;}virtual ~Derived(){ } }; int main() {Base *pBase = new Derived;pBase->vFoo(); //"Derived::vFoo()"delete pBase;return 0; } 多態(tài)舉例

可看到,由于基類指針實際指向派生類實例,所以實際調用的是派生類里的vFoo()函數。

但嘗試?pBase->Other();//編譯出錯?,雖然pBase指向派生類實例,但指針本身的類型卻決定了它所能調用的函數范圍。

強制轉換下呢:?((Derived*)pBase)->Other();//"Derived::Other()"?,成功了。

但如果這樣呢:

Base *pBase = new Base; ((Derived*)pBase)->Other();

仍然成功了,正確輸出。實際Other函數可以直接使用Derived::Other()來調用的,因為函數里沒交互數據成員。但如果交互了呢:

//Derived類里: public:int a = 6;//C++11void Other(){cout << a << endl;//隨機數字,如73756547a = 100;} };//main里 Base *pBase = new Base; ((Derived*)pBase)->Other();

運行后竟仍然成功了。但從輸出的a是隨機數字可以看出int a =6;并沒有執(zhí)行過,因為new的是Base實例。這里我們雖依然運行成功,但從程序上看,這是不對的。如果Derived類封裝的更復雜(比如在構造函數里new, Other里delete),可能肯定運行時會崩潰!所以c語言形式的強制轉換在此種情況下是不安全的。

可能問,為什么一定要調用Other函數呢,如果一定要在使用多態(tài)時調用它,在基類里添加Other函數并聲明它為虛函數不就行了。是的,這樣可以。但有時,比如我使用了一個第三方庫(封裝到lib里,只提供了它的頭文件),我在從它繼承的派生類中添加了新函數,并想在多態(tài)下使用。此時是不可能在第三方庫里添加虛函數的,因為庫不能重新編譯。這時就需要安全的類型轉換了。dynamic_cast就可以在此種情況下起作用:

void foo(Base *p) {Derived* pChild = dynamic_cast<Derived*>(p);if(pChild)pChild->Other();else{//不指向派生類實例時的處理 } } //引用時 void foo2(Base &b) {try{Derived& pChild = dynamic_cast<Derived&>(b);pChild.Other();}catch(std::bad_cast){//不指向派生類實例時的處理 } }


對基類指針,不屬于某個派生類實例將返回null,這樣可用來判斷類型:

void foo(Base *p) {if(dynamic_cast<Derived1*>(p)){//屬于Derived1類 }else if(dynamic_cast<Derived2*>(p)){//屬于Derived2類 }//... }

?


typeid:

http://www.cppblog.com/smagle/archive/2010/05/14/115286.aspx這篇寫的很好,我就不怎么寫了。。。直接貼它的幾個例子吧

需要注意(仍根據上文例子):

Base *pBase = new Derived;
cout << typeid(pBase).name() << endl; //class Base* ? 雖然基類有虛函數且指針指向派生類對象,但仍輸出指針類型本身
cout << typeid(*pBase).name() << endl;//class Derived
Base &rD = *pBase;//class Derived ? //注意,引用和指針結果不同

//所以typeid能對含虛函數的類類型(對象本身或引用)判斷出其指向的對象的類型信息,對指針無用。

例子:

#include <iostream> using namespace std;class Base { }; class Derived: public Base { };void foo() { } int main() {Base b, *pb;pb = NULL;Derived d;cout << typeid(int).name() << endl<< typeid(unsigned).name() << endl<< typeid(long).name() << endl<< typeid(unsigned long).name() << endl<< typeid(char).name() << endl<< typeid(unsigned char).name() << endl<< typeid(float).name() << endl<< typeid(double).name() << endl<< typeid(string).name() << endl << endl//函數類型和函數指針也可以<< typeid(void (*)(int, int)).name() << endl<< typeid(foo).name() << endl << endl<< typeid(Base).name() << endl<< typeid(b).name()<<endl<< typeid(pb).name()<<endl //雖然指向NULL,但本身類型是Base *<< typeid(Derived).name() << endl<< typeid(d).name()<<endl<< typeid(type_info).name() << endl;return 0; } 基本類型與一般類

?

#include <iostream> using namespace std;class Base { public:virtual void foo(){}virtual ~Base(){} }; class Derived: public Base { };int main() {Base *pd = new Derived;cout << typeid(pd).name() << endl //class Base *<< typeid(*pd).name() << endl;Base &rD = *pd;cout << typeid(rD).name() << endl;//雖無法從指針本身上判斷,但可對其解引用if(typeid(Derived) == typeid(*pd))cout << "類型相同" << endl;elsecout << "類型不同" << endl;delete pd;return 0; }

轉載于:https://www.cnblogs.com/sfqtsh/p/5143678.html

總結

以上是生活随笔為你收集整理的RTTI: dynamic_cast typeid的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。