dynamic_cast

 

 

編輯本段用法

  dynamic_cast < type-id > ( expression )
 
  該運算符把expression轉換成type-id類型的對象。Type-id必須是類的指針、類的引用或者void*;
 
  如果type-id是類指針類型,那麼expression也必須是一個指針,如果type-id是一個引用,那麼expression也必須是一個引用。
 
  dynamic_cast運算符可以在執行期決定真正的類型。如果downcast是安全的(也就說,如果基類指針或者引用確實指向一個派生類對象)這個運算符會傳回適當轉型過的指針。如果downcast不安全,這個運算符會傳回空指針(也就是說,基類指針或者引用沒有指向一個派生類對象)。
 
  dynamic_cast主要用於類層次間的上行轉換和下行轉換,還可以用於類之間的交叉轉換。
 
  在類層次間進行上行轉換時,dynamic_cast和static_cast的效果是一樣的;
 
  在進行下行轉換時,dynamic_cast具有類型檢查的功能,比static_cast更安全。
 
  class B{
 
  public:
 
  int m_iNum;
 
  virtual void foo();
 
  };
 
  class D:public B{
 
  public:
 
  char *m_szName[100];
 
  };
 
  void func(B *pb){
 
  D *pd1 = static_cast<D *>(pb);
 
  D *pd2 = dynamic_cast<D *>(pb);
 
  }
 
  在上面的代碼段中,如果pb指向一個D類型的對象,pd1和pd2是一樣的,並且對這兩個指針執行D類型的任何操作都是安全的;
 
  但是,如果pb指向的是一個B類型的對象,那麼pd1將是一個指向該對象的指針,對它進行D類型的操作將是不安全的(如訪問m_szName),
 
  而pd2將是一個空指針。
 

編輯本段注意事項

  B要有虛函數,否則會編譯出錯;static_cast則沒有這個限制。
 
  B中需要檢測有虛函數的原因:類中存在虛函數,就說明它有想要讓基類指針或引用指向派生類對象的情況,此時轉換纔有意義。
 
  這是由於運行時類型檢查需要運行時類型信息,而這個信息存儲在類的虛函數表(關於虛函數表的概念,詳細可見<Inside c++ object model>)中,只有定義了虛函數的類纔有虛函數表,
 
  沒有定義虛函數的類是沒有虛函數表的。
 
  另外,dynamic_cast還支持交叉轉換(cross cast)。如下代碼所示:
 
  class A{
 
  public:
 
  int m_iNum;
 
  virtual void f(){}
 
  };
 
  class B:public A{
 
  };
 
  class D:public A{
 
  };
 
  void foo(){
 
  B *pb = new B;
 
  pb->m_iNum = 100;
 
  D *pd1 = static_cast<D *>(pb); //compile error
 
  D *pd2 = dynamic_cast<D *>(pb); //pd2 is NULL
 
  delete pb;
 
  }
 
  在函數foo中,使用static_cast進行轉換是不被允許的,將在編譯時出錯,而使用 dynamic_cast的轉換則是允許的,結果是空指針。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章