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(調用類型轉換函數)。
不適用於:
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 轉指針,不允許反過來)。