C/C++強制/自動類型轉換

C語言自動類型轉換

unsigned 即爲 unsigned int ,此時可以省略int 只寫unsigned 
隱式的類型轉換是安全的,而顯示的類型轉換是存在風險的。
 
 
 
C語言強制類型轉換

C語言中 涉及地址間強制類型轉換 特別要注意 字節對齊 的問題
unsigned int value = 1024;  // 4 個 字節  
cout << hex << &value << endl;
 
bool *p = (bool*)(&value);
cout << hex << p << endl;
 
p++;
cout << p << endl;
 
bool condition = *((bool *)(&value));  //(bool *)(&value);取的是第一位的地址
if (condition)
    printf("condition=1");
else
    printf("condition=0");
 
// 需要從大小端存儲方式分析
 
    struct point{
        int a;
        int *b;
    }p;
    p.a = 300;
    p.b = (int*)500; // p.b爲地址,地址,地址!!!!
//     ptr指向地址爲500的位置,其中的內容是未知的
//    (前提是系統允許用戶操作500這個地址)
    printf("%d \n", 10 + p.a  );// 值改變
    printf("%d \n", 100 + p.a );
//    p.b爲地址,+表示偏移
    printf("%d \n",  p.b + 1);  // 指針p.b偏移1 * 4,
    printf("%d \n",  p.b + 100); // 指針p.b偏移100 * 4
    printf("%d \n",  p.b + p.a); // 指針p.b偏移p.a * 4
 
 
 
C++ 強制類型轉換

static_cast
static_cast<newType> (data) 
 
double a = 19.95
int b = static_cast<int> (a)
 
適用於:
  • 原有的自動類型轉換。如:short -> int、const -> 非const
  • void指針和具體類型指針間的轉換。如:void * -> int *、 char * -> void *
  • 有轉換構造函數或者類型轉換函數的類與其它類型之間的轉換。如 double 轉 Complex(調用轉換構造函數)、Complex 轉 double(調用類型轉換函數)。
不適用於:
  • 兩個具體類型指針之間的轉換,例如int *轉double *、Student *轉int *等(不同類型數據存儲格式、長度都不一樣)
  • 不能用來去掉表達式的 const 修飾和 volatile 修飾。換句話說,不能將 const/volatile 類型轉換爲非 const/volatile 類型。
 
 
const_cast
const_cast<newType> (data)
 
const int n = 100;
int *p = const_cast<int*>(&n);
*p = 12345;
 
 
const char *p = str1.c_str();
char* pp = const_cast<char*>(p);
它用來去掉表達式的 const 修飾屬性或 volatile 修飾屬性。換句話說,const_cast 就是用來將 const/volatile 類型轉換爲非 const/volatile 類型
 
 
 
dynamic_cast(涉及到RTTI
使用形式如下:
dynamic_cast<type*  >(e);
dynamic_cast<type&  >(e);
dynamic_cast<type&& >(e);
type必須是一個類 類型,type 和 en 必須同時是指針類型或者引用類型或void *
對於指針,如果轉換失敗將返回 NULL;對於引用,如果轉換失敗將拋出std::bad_cast異常
dynamic_cast 用於在類的繼承類之間進行類型轉換。它依賴於RTTI(這就要求基類必須擁有虛函數,因爲RTTI信息存儲在虛函數表中),它允許向上轉型也允許向下轉型向上轉型(派生類指針或引用轉基類)是無條件的,不會進行任何檢測,所以都能成功;(派轉基)向下轉型(基類指針或引用轉派生類)的前提必須是安全的,在程序運行期間要藉助 RTTI 進行類型轉換,這就要求基類必須包含虛函數,而static_cast在編譯期間完成類型轉換。(基轉派)
e能成功轉換爲type*類型的情況有三種:
1)e的類型就是type的類型時,一定會轉換成功(不要求有虛函數的限定)。(本身轉換)
2)e的類型是目標type的公有派生類:派生類向基類轉換一定會成功(不要求有虛函數的限定)。(派轉基)
 
3)e的類型是目標type的基類,(基類必須要有虛函數)(基轉派)
   當e是指針指向派生類對象,或者基類引用引用派生類對象時,類型轉換纔會成功,
   當e指向基類對象,試圖轉換爲派生類對象時,轉換失敗
 
 
注:上指父類(基類),下指子類(派生類)
 
 
reinterpret_cast
reinterpret_cast<newType> (data)
 
char str[]="abcdefgh";
float *p1 = reinterpret_cast<float*>(str); //用一個 float 指針來操作一個 char 數組是一件多麼荒誕和危險的事情
cout<<*p1<<endl;
 
是“重新解釋”的意思,顧名思義,reinterpret_cast 這種轉換僅僅是對二進制位的重新解釋,不會藉助已有的轉換規則對數據進行調整,非常簡單粗暴,所以十分危險,不到萬不得已時應避免使用
可以用於兩個具體類型指針之間的轉換、int 和指針之間的轉換(有些編譯器只允許 int 轉指針,不允許反過來)。
 
 
 
 
 
 
 
 
 
 
 
 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章