1. 程式人生 > 其它 >C++型別轉換

C++型別轉換

C++有可以使用static_cast、dynamic_cast、const_cast、reinterpret_cast來進行型別的轉換。現在將每一個的使用方法進行一下總結。

1.static_cast

這個運算子的功能是把一個表示式轉換為某種型別,但是沒有執行時型別檢查來保證轉換的安全性。可以用來轉換的型別主要如下:

  • 類中基類和派生類之間的指標或者引用的轉換:向上轉換是安全的(派生類的指標轉換為基類),但是向下轉換的時候由於沒有型別檢查,所有是不安全的。
  • 基本資料型別之間的轉換。
  • 空指標轉換為目標型別的空指標。
  • 任何型別的表示式轉換為void型別。

static_cast不能把原來表示式中的const、volatile、_unaligned屬性轉換成沒有。請看下面例子

1    char firstChar = 'A';
2    int firstInt = static_cast<int>(firstChar);
3    const char* constStr = "this is a test string";
4    char* str = static_cast<char*>(constStr);

上面的第4行程式碼是不能編譯通過的。

2.dynamic_cast

dynamic_cast的轉換需要目標型別和源物件有一定的關係:繼承關係。換句話說就是dynamic_cast就是用來檢查兩者是否有繼承關係,所有dynamic_cast只能接受類物件的指標或者是引用的類轉換。用法表示式如下:

dynamic_cast<type_id>(expession)。type_id只能是類的指標、引用或者是void*。如果type_id是一個指標或者引用,那麼expression也必須是指標或者引用,type_id和expression必須對應起來。

dynamic_cast在執行的時候決定真正的型別,如果轉換是安全的,dynamic_cast就會傳回適當的轉換過的指標,如果轉換是不安全的,就會返回空指標。

在類層次向上轉換的時候,dynamic_cast和static_cast的效果是一樣的。

在類層次向下轉換的時候,由於dynamic_cast會做型別檢查,所有比static_cast更加的安全。如下的例子:

class person
{
public:
   int n_num;
   virtual void doSomething()
   {
      cout << "i am a person" << endl;
   }
};
class colorPerson :public person
{
public:
   char* mName;
};
void change(person *person)
{
   colorPerson * cp1 = static_cast<colorPerson*>(person);
   cout << "start to call cp1" << endl;
   if (cp1 != NULL)
   {
      cp1->doSomething();
   }
   else 
   {
      cout << "cp1 is null" << endl;
   }
   colorPerson *cp2 = dynamic_cast<colorPerson*>(person);
   cout << "start to call cp2" << endl;
   if (cp2!= NULL)
   {
      cp2->doSomething();
   }
   else
   {
      cout << "cp2 is null" << endl;
   }
}
int main()
{
   person *p1=new person();
   change(p1);
   colorPerson *cp1 = new colorPerson();
   change(cp1);

    return 0;
}
View Code

輸出結果是這樣的:

在定義person類的時候,我們是定義了一個virtual的dosomething(),這個virtual對應dynamic_cat是必須的,如果沒有virtual,就會報編譯錯誤。因為dynamic_cast轉換是在執行時進行轉換,執行時轉換就需要知道類物件的資訊(繼承關係等)。如何在執行時獲取到這個資訊——虛擬函式表。