static_cast、dynamic_cast、reinterpret_cast、和const_cast
轉自:https://blog.csdn.net/gyymen/article/details/53534200
C++的型別轉換符:static_cast、dynamic_cast、reinterpret_cast、和const_cast
形式:class_name <type>(expression)
,其中class_name為以上4種,type是轉換的目標型別,expression是要轉換的值。
1、static_cast
任何具有明確定義的型別轉換,只要不包含底層const,都可以使用static_const。在編譯期強制轉換。
頂層const:表示指標本身是個常量。如:int *const p;
底層const:表示指標所指的物件是一個常量。如:int const *p;
該運算子沒有執行時型別檢查來保證轉換的安全性。
①用於類層次結構中基類和子類之間指標或引用的轉換。
進行上行轉換(把子類的指標或引用轉換成基類表示)是安全的;
進行下行轉換(把基類指標或引用轉換成子類表示)時,由於沒有動態型別檢查,所以是不安全的。
涉及到類,static_cast只能在有相互聯絡的型別中進行相互轉換。
class A {}; class B:public A {}; class C {}; int main() { A* a=new A; B* b; C* c; b=static_cast<B>(a); // 編譯不會報錯, B類繼承A類 c=static_cast<B>(a); // 編譯報錯, C類與A類沒有任何關係 return 1; }
②用於基本資料型別之間的轉換,如把int轉換成char,把int轉換成enum。
③把空指標轉換成目標型別的空指標。
④把任何型別的表示式轉換成void型別。
注意:static_cast不能轉換掉expression的const、volitale、或者__unaligned屬性。
2、const_cast
const_cast只能改變運算物件的底層const,用來移除變數的const或volatile限定符。
const char m = 't'; const char *cm = &m; char *n = const_cast<char*>(cm); *n = 'a'; cout << *n << endl; //輸出a
但是,const_cast是不能用來執行任何型別的轉換的,這樣都會引起編譯錯誤的!
const char m = 't';
const char *cm = &m;
int *n = const_cast<int*>(cm); //編譯出錯,const_cast只能調節型別限定符,不能更改基礎型別
*n = 'a';
cout << *n << endl;
3、dynamic_cast
Type必須是類的指標、類的引用或者void *,用於將基類的指標或引用安全地轉換成派生類的指標或引用。
注意:
(1)dynamic_cast在執行期強制轉換,執行時要進行型別檢查,較安全。
(2)不能用於內建的基本資料型別的強制轉換。
涉及到類,使用dynamic_cast進行轉換的,基類中一定要有虛擬函式,否則編譯不通過。
對指標進行dynamic_cast,失敗返回null,成功返回正常cast後的物件指標;
對引用進行dynamic_cast,失敗丟擲一個異常bad_cast,成功返回正常cast後的物件引用。
對於“向上轉換”(即派生類指標或引用轉換為其基類型別)都是安全地。
對於“向下轉型”有兩種情況:
第一,基類指標所指物件是派生類型別,這種轉換是安全的;
第二,基類指標所指物件為基類型別,dynamic_cast在執行時做檢查,轉換失敗,返回結果為0。
#include<iostream>
using namespace std;
class Base{
public:
Base(){};
virtual void Show(){cout<<"This is Base calss";}
};
class Derived:public Base{
public:
Derived(){};
void Show(){cout<<"This is Derived class";}
};
int main(){
//這是第一種情況
Base* base = new Derived;
if(Derived *der= dynamic_cast<Derived*>(base)) {
cout<<"第一種情況轉換成功"<<endl;
der->Show();
cout<<endl;
}
//這是第二種情況
Base * base1 = new Base;
if(Derived *der1 = dynamic_cast<Derived*>(base1)) {
cout<<"第二種情況轉換成功"<<endl;
der1->Show();
}
else {
cout<<"第二種情況轉換失敗"<<endl;
}
delete(base);
delete(base1);
return 0;
}
輸出:
第一種情況轉換成功
This is Derived class
第二種情況轉換失敗
4、reinterpret_cast
在指標之間轉換,將一個型別的指標轉換為另一個型別的指標,無關型別;
將指標值轉換為一個整型數,但不能用於非指標型別的轉換。
#include<iostream>
using namespace std;
int main() {
int a=10;
int *i=&a;
long pc=reinterpret_cast<long>(i);//把一個指標轉換為一個整數,即取出地址值
char *str=reinterpret_cast<char *>(i);//把int*轉換為char *(比int型小),無輸出
long *l=reinterpret_cast<long *>(i);//把int *轉換為long *(比int型大),取出地址值(即i值)輸出
cout<<*i<<endl;
cout<<hex<<pc<<endl;
cout<<i<<endl;
cout<<"char:"<<str<<endl;
cout<<l<<endl;
return 0;
}
輸出:
10
28fedc
0x28fedc
char:
0x28fedc
總結:
去const屬性用const_cast
基本型別轉換用static_cast
多型類之間的型別轉換用daynamic_cast
不同型別的指標型別轉換用reinterpreter_cast