天天看點

使用dynamic_cast的一點心得

  C++程式員大多喜歡使用強制類型轉換(我也是),盡管它是C遺留下來的,盡管它存在這樣那樣的缺點,但是你不能不承認它使用起來很友善,而且絕大多數情況下是不會産生問題的.極少數情況下可能會存在類型轉換失敗的情況,這時候就需要使用到dynamic_cast了,這裡提到的"極少數情況"是這樣的:如果有繼承或多重繼承的類對象,你在某些情況下得到某個對象的指針,而你又想将其轉換為某個特定類型,但是由于C++中對象類型的多态性(它可以是多種類型),你又不能确定(在運作時)這麼做一定會成功,此時可以使用dynamic_cast,充分利用C++的運作時檢查機制.隻是用語言描述太抽象了,舉個例子吧.

class A{...}; 

class B:public A{...}; 

class C:public B{...}; 

void Fun1(B* pB) 

A* pA  = (A*)pB; 

C* pC  = (C*)pB; 

... 

  Fun1函數使用強制類型轉換将pB轉換為A*或C*,看出什麼的問題了嗎?

  如果這樣調用Fun1:

                             Fun1(((B*)new C));

的确不會有問題,但如果是這樣呢: 

                             Fun1(new B);

pC不會為NULL,能夠想到使用pC指針時就程式就悲劇了.

更嚴重情況下,如果是這樣: 

                             Fun1((B*)0X00005678);//0X00005678是一個随機值

pA,PC就不會是NULL,強制類型轉換總是能夠成功的,但使用這兩個指針時程式肯定崩潰.當然你可以使用異常處理機制來處理這樣的錯誤,不過這有點大才小用的感覺,最好能夠找到一種能夠檢查出類型轉換能否成功的辦法.這時dynamic_cast就能大顯身手了.

A* pA  = dynamic_cast<A*>pB;// upcast. 

if (NULL == pA){...} 

C* pC  = dynamic_cast<C*>pB;// downcast. 

if (NULL == pC){...} 

    dynamic_cast的具體作用這裡不詳細解釋,僅僅抛磚引玉做一點說明.這裡假設:

                              dynamic_cast < ObjectType-ID* > ( ObjectType*)

  如果要成功地将ObjectType*轉換為ObjectType-ID*,則必須存在這種可能性才可以,也就是說ObjectType*指向的對象要"包含"ObjectType-ID*指向的對象,如此才能夠成功.就上面的例子來說,C對象"包含"B對象,而B對象"包含"A對象,如果:

                      A* pA = new B;

那麼

                   B* pB  = dynamic_cast<B*>pA;// OK.

                   C* pC  = dynamic_cast<C*>pA;// Fail.

如果說你不能确定這種包含關系,最好使用dynamic_cast.

 實際上可以把dynamic_cast看做是強制類型轉換的一個子集,看成是更嚴格檢查的強制類型轉換,因為"更嚴格"是以能夠檢查出來錯誤.

  最後提一點,使用dynamic_cast,不要忘了編譯選項GR.

本文轉自jetyi51CTO部落格,原文連結: http://blog.51cto.com/jetyi/671256,如需轉載請自行聯系原作者

繼續閱讀