1. 程式人生 > >c/c++類型轉換相關總結

c/c++類型轉換相關總結

兩個指針 自動 隱式轉換 需要 const 賦值 vss 進行 結構

在c語言中存在兩種類型轉換:顯式類型轉換和隱式類型轉換;

  顯示類型轉換:在類型前加上(type)變量,對變量進行的轉換,程序員自己顯式添加;

  char *ptra = (char*)ptrb;

  void *ptrc = (void*)ptrd;

  隱式轉換:不同數據結構之間賦值和運算,函數調用傳遞參數時,編譯器自動完成;

  char ch = 0;

  int i = ch;

在c++中的類型轉換:

  通過上面兩種方式,c語言中大部分的類型轉換都是以順利進行。至於能不能進行轉換,轉換後的結果如何,編譯器不管,需要用戶自己去控制。

  c++繼承了c中的隱式和顯式轉換的方式。但是這種轉換並不是安全和嚴格的,加上c++本身對象模型的復雜性,c++增加了四個顯示轉換的關鍵字。(c++是強類型語言)

  (static_cast,dynamic_cast,const_static,reinterpret_cast)

  1、static_cast

  用法:static_cast<type-id>(exdivssion)

  該運算符把exdivssion轉換為type-id類型,但沒有運行時類型檢查來保證轉換的安全性。

  它主要有如下幾種用法:

  1)用於類層結構中基類和子類之間指針或引用的轉換。

    進行上行轉換是安全的。(把子類的指針或引用轉換為基類表示)

    進行下行轉換時,由於沒有動態類型檢查,所以是不安全的。(把基類指針或引用轉換成子類表示)

  2)用於基本數據類型之間的轉換,如把int轉換成char,把int轉換成enum,這種轉換的安全性也要開發人員來保證。

  3)把空指針轉換成目標類型的空指針。

  4)把任何類型的表達式轉換成void類型。

  註意:static_cast不能替換掉exdivssion的const、volitale、或者unaligned屬性。

  2、dynamic_cast

  用法:dynamic_cast<type-id>(exdivssion)

  該運算符把exdivssion轉換成tepe-id類型的對象。type-id必須是類的指針、類的引用或者void*;

  如果type-id是類指針類型,那麽exdivssion也必須是一個指針,如果type-id是一個引用,那麽exdivssion也必須是一個引用。

  dynamic_cast主要用於類層次間的上行轉換和下行轉換,還可以用於類之間的交叉轉換。

  在類層次進行上行轉換時,dynamix_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將是一個空指針。

  另外要註意:dynamic_cast轉換對象時被轉換對象類型必須是多態類型,即被轉換對象必須公有繼承自其他類,或其擁有虛函數。即B要有虛函數,否則會編譯錯誤;static_cast則沒有這個限制,這是由於運行時類型檢查需要運行時類型信息,而這個信息存儲在累的虛函數表中,只有定義了虛函數的類才有虛函數表,沒有定義虛函數的類是沒有虛函數表的。

  另外,dynamic_cast還支持交叉轉換(crosscast)。如下代碼所示。

  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)); //編譯錯誤;

  D *pd1 = dynamic_cast<D>((pb));

  delete pb;

  }

  在函數foo中,使用static_cast進行轉換是不被允許的,將在編譯時出錯;而使用dynamic_cast的轉換則是允許的,結果是空指針;

c/c++類型轉換相關總結