1. 程式人生 > >C++中,有哪四個與型別轉換相關的關鍵字

C++中,有哪四個與型別轉換相關的關鍵字

C++與型別轉換相關的四個關鍵字有:const_cast, static_cast, dynamic_cast, reinterpret_cast

  • static_cast——運算子完成相關型別之間的轉換

【特點】:靜態轉換,在編譯處理期間。
【應用場合】:主要用於C++中內建的基本資料型別之間的轉換,但是沒有執行時型別的檢測來保證轉換的安全性。

  1. 用於基類和子類之間的指標或引用之間的轉換,這種轉換把子類的指標或引用轉換為基類表示是安全的;進行下行轉換,把積累的指標或引用轉換為子類表示時,由於沒有進行動態型別檢測,所以是不安全的。
  2. 把void型別的指標轉換成目標型別的指標(不安全)。
  3. 不能用於兩個不相關的型別轉換。
  4. 不能把const物件轉換成非const物件。
1int m=10;
    double n=static_cast < int > m;

例2int * q=static_cast < int* >(malloc(100));
  • reinterpret_cast——處理互不相關型別之間的轉換

【特點】: 重解釋型別轉換
【應用場合】:它有著和c風格強制型別轉換同樣的功能;它可以轉化任何的內建資料型別為其他的型別,同時它也可以把任何型別的指標轉化為其他的型別;它的機理是對二進位制進行重新的解釋,不會改變原來的格式。

例: int a=10;
   double* b=reinterpret_cast<double*>(a); 
   //b的轉換結果為0x0000000a
  • dynamic_cast——處理基型別到派生型別的轉換

【應用場景】:基類必須有虛擬函式,即為多型時,可以轉換

class Base
{
public:
   virtual int test(){return 0;} //基類中存在虛擬函式,故在派生類中存在虛擬函式指標指向虛擬函式表。
};

class Derived:public Base
{
public:
   virtual int test(){return 1;}
};

int
main() { Base cbase; Derived cderived; Base *p1=new Base; Base *p2=new Derived; Derived* pD1=dynamic_cast<Derived*>(p1);//p1沒有真正指向派生類,pD1置為0 Derived* pD2=dynamic_cast<Derived*>(p2); //正確 //Derived& pd1=dynamic_cast<Derived&>(*p1);//p1沒有真正指向派生類,pd1丟擲異常 Derived& pd2=dynamic_cast<Derived&>(*p2);//正確 return 0; }
  • const_cast用來移除變數的const或volatile限定符

【特點】:去常轉換,編譯時執行。
【應用場合】:const_cast操作不能在不同的種類間轉換。相反,它僅僅把它作用的表示式轉換成常量。它可以使一個本來不是const型別的資料轉換成const型別的,或者把const屬性去掉。

注:
volatile的作用是: 作為指令關鍵字,確保本條指令不會因編譯器的優化而省略,且要求每次直接讀值.
簡單地說就是防止編譯器對程式碼進行優化.比如如下程式碼:

a=1;
a=2;
a=3;
a=4;

對外部硬體而言,上述四條語句分別表示不同的操作,會產生四種不同的動作,但是編譯器卻會對上述四條語句進行優化,認為只有a=4(即忽略前三條語句,只產生一條機器程式碼)。如果鍵入volatile,則編譯器會逐一的進行編譯併產生相應的機器程式碼(產生四條程式碼)

補充

在上面四個型別轉化關鍵字中,除了static_cast,其他的三個都有可能涉及到指標的型別轉換。
從本質上來說,指標的型別不同,並沒有產生很大的差異,他們都是需要足夠的記憶體來存放一個機器地址。“指向不同型別之各指標”間的差異,既不在其指標表示法不同,也不在其內容(代表一個地址)不同,而是在其所定址出來的object不同。也就是說,“指標型別”會教導編譯器如何解釋某個特定地址中的記憶體內容及其大小。

所以,轉換(cast)其實是一種編譯器指令。大部分情況下它並不改變一個指標所含的真正地址,它隻影響“被指出之記憶體大小和其內容”的解釋方式。