c++ 数据类型转换: static_cast dynamic_cast reinterpret_cast const_cast
c++ 數(shù)據(jù)類型轉(zhuǎn)換: static_cast dynamic_cast reinterpret_cast const_cast
【版權(quán)聲明】轉(zhuǎn)載請注明出處?http://www.cnblogs.com/TenosDoIt/p/3175217.html【目錄】
引言
static_cast 定義
dynamic_cast 定義
舉例:下行轉(zhuǎn)換(把基類的指針或引用轉(zhuǎn)換成子類表示)
舉例:上行轉(zhuǎn)換(把子類的指針或引用轉(zhuǎn)換成基類表示)
舉例: static_cast 用于基本類型之間、基本類型指針和空指針間的轉(zhuǎn)換
reinterpret_cast 定義
舉例:reinterpret_cast用法
const_cast 定義
舉例:const_cast用法
總結(jié)
?
c語言中我們經(jīng)常使用類似于 int a =(int)3.14等這種強制類型轉(zhuǎn)換
標準c++的類型轉(zhuǎn)換符:static_cast 、dynamic_cast、 reindivter_cast、 const_cast, 以下分別介紹他們的用法以及舉例說明
以下代碼編譯運行環(huán)境:codeblock with gcc in win7(x64)
【1】static_cast?
用法:static_cast?< type-id > ( exdivssion )?
該運算符把exdivssion轉(zhuǎn)換為type-id類型,但沒有運行時類型檢查來保證轉(zhuǎn)換的安全性。它主要有如下幾種用法:
①用于類層次結(jié)構(gòu)中基類和子類之間指針或引用的轉(zhuǎn)換。
進行上行轉(zhuǎn)換(把子類的指針或引用轉(zhuǎn)換成基類表示)是安全的;
進行下行轉(zhuǎn)換(把基類指針或引用轉(zhuǎn)換成子類表示)時,由于沒有動態(tài)類型檢查,所以是不安全的。
②用于基本數(shù)據(jù)類型之間的轉(zhuǎn)換,如把int轉(zhuǎn)換成char,把int轉(zhuǎn)換成enum。這種轉(zhuǎn)換的安全性也要開發(fā)人員來保證。
③把空指針轉(zhuǎn)換成目標類型的空指針。
④把任何類型的表達式轉(zhuǎn)換成void類型。
注意:static_cast?不能轉(zhuǎn)換掉exdivssion的const、volitale、或者__unaligned屬性。
msdn官方解釋:http://msdn.microsoft.com/en-us/library/c36yw7x9(v=vs.80).aspx
【2】dynamic_cast
用法:dynamic_cast < type-id > ( exdivssion )
該運算符把exdivssion轉(zhuǎn)換成type-id類型的對象。Type-id必須是類的指針、類的引用或者void *;
如果type-id是類指針類型,那么exdivssion也必須是一個指針,如果type-id是一個引用,那么exdivssion也必須是一個引用。
dynamic_cast主要用于類層次間的上行轉(zhuǎn)換和下行轉(zhuǎn)換,還可以用于類之間的交叉轉(zhuǎn)換。
在類層次間進行上行轉(zhuǎn)換時,dynamic_cast和static_cast?的效果是一樣的;
在進行下行轉(zhuǎn)換時,dynamic_cast具有類型檢查的功能,比static_cast?更安全。
msdn官方解釋:http://msdn.microsoft.com/en-us/library/cby9kycs(v=vs.80).aspx
?
舉例:下行轉(zhuǎn)換(把基類的指針或引用轉(zhuǎn)換成子類表示)
需要注意的是如果基類中不含虛函數(shù),dynamic_cast 下行轉(zhuǎn)換編譯會出錯
1 #include<iostream>2 using namespace std;3 4 class father5 {6 public:7 void fun1()8 {9 cout<<"this is father fun1 call\n"; 10 } 11 virtual void fun() 12 { 13 cout<<"this is father fun call\n"; 14 } 15 }; 16 17 class son: public father 18 { 19 public: 20 void fun2() 21 { 22 cout<<"this is son fun2 call\n"; 23 } 24 void fun() 25 { 26 cout<<"this is the son fun call\n"; 27 } 28 int k; 29 }; 30 31 int main() 32 { 33 father *pf, f; 34 son *ps, s; 35 36 pf = &f;// 基類的指針指向基類對象 37 ps = static_cast<son *>(pf);//這種轉(zhuǎn)換是不安全的,行為是不確定的 38 if(ps != NULL) 39 { 40 ps->fun(); //在本文編譯環(huán)境下,執(zhí)行父類的fun 41 //本文編譯環(huán)境下,一下語句可以執(zhí)行 42 ps->fun2(); 43 ps->k = 1; 44 } 45 ps = dynamic_cast<son *>(pf);//轉(zhuǎn)換后ps = NULL 46 if(ps == NULL) 47 cout<<"dynamic_cast: ps = NULL\n"; 48 cout<<"-----------------------------------------------------------------\n"; 49 pf = &s; //基類指針開始指向子類對象 50 //此時,兩種轉(zhuǎn)換都是安全的 51 ps = static_cast<son *>(pf); 52 if(ps != NULL) 53 { 54 ps->fun(); 55 ps->fun2(); 56 ps->k = 1; 57 } 58 ps = dynamic_cast<son *>(pf);//轉(zhuǎn)換后ps = NULL 59 if(ps != NULL) 60 { 61 ps->fun(); 62 ps->fun2(); 63 ps->k = 2; 64 } 65 }結(jié)果:
舉例:上行轉(zhuǎn)換(把子類的指針或引用轉(zhuǎn)換成基類表示)
1 //類定義同上2 int main()3 {4 father *pf, f;5 son *ps, s;6 7 ps = &s;// 子類的指針指向子類對象8 //此時兩種轉(zhuǎn)換都是安全的9 pf = static_cast<father *>(ps); 10 if(pf != NULL) 11 { 12 pf->fun(); 13 } 14 pf = dynamic_cast<father *>(ps); 15 if(pf != NULL) 16 { 17 pf->fun(); 18 } 19 20 }舉例: static_cast 用于基本類型之間、基本類型指針和空指針間的轉(zhuǎn)換(不能用于基本類型指針之間轉(zhuǎn)換)。
注意:基本類型由于表示數(shù)值范圍的不同,因此需要用戶保證轉(zhuǎn)換的安全。另外dynamic_cast不能用于此類轉(zhuǎn)換
1 int main()2 {3 //基本類型間的轉(zhuǎn)換,需要用戶保證安全4 int a = 1000;5 char c = static_cast<char>(a);//不安全,1000超過了char的表示范圍6 cout<<c<<endl;//輸出空7 a = 49;8 c = static_cast<char>(a);//安全,輸出字符‘1’9 cout<<c<<endl; 10 //c = dynamic_cast<char>(a); 錯誤 11 cout<<"-----------------------------------------------------------------\n"; 12 //void *和基本類型指針的轉(zhuǎn)換,需要用戶保證轉(zhuǎn)換安全 13 a = 49; 14 void *pv; 15 pv = &a; 16 int *pi = static_cast<int *>(pv);//void * 轉(zhuǎn)換為int * 17 cout<<*pi<<endl; //輸出49 18 //pi = dynamic_cast<int *>(pv); 錯誤 19 char *pc = static_cast<char *>(pv);//void *轉(zhuǎn)char* 20 cout<<*pc<<endl;//輸出字符‘1’ 21 void *pv2 = static_cast<void *>(pc);// char * 轉(zhuǎn)void * 22 cout<<*((char *)pv2)<<endl;輸出字符‘1’ 23 }?
【3】reinterpret_cast
用法:reinterpret_cast<type-id> (exdivssion)
reinterpret_cast運算符是用來處理無關(guān)類型之間的轉(zhuǎn)換;它會產(chǎn)生一個新的值,這個值會有與原始參數(shù)(expressoin)有完全相同的比特位。按照reinterpret的字面意思“重新解釋”,即對數(shù)據(jù)的比特位重新解釋。
IBM的C++指南?里明確告訴了我們reinterpret_cast可以,或者說應該在什么地方用來作為轉(zhuǎn)換運算符:
- 從指針類型到一個足夠大的整數(shù)類型
- 從整數(shù)類型或者枚舉類型到指針類型
- 從一個指向函數(shù)的指針到另一個不同類型的指向函數(shù)的指針
- 從一個指向?qū)ο蟮闹羔樀搅硪粋€不同類型的指向?qū)ο蟮闹羔?/li>
- 從一個指向類函數(shù)成員的指針到另一個指向不同類型的函數(shù)成員的指針
- 從一個指向類數(shù)據(jù)成員的指針到另一個指向不同類型的數(shù)據(jù)成員的指針
總結(jié)來說:reinterpret_cast用在任意指針(或引用)類型之間的轉(zhuǎn)換;以及指針與足夠大的整數(shù)類型之間的轉(zhuǎn)換;從整數(shù)類型(包括枚舉類型)到指針類型,無視大小。
注意:static_cast?不能轉(zhuǎn)換掉exdivssion的const、volitale、或者__unaligned屬性。
msdn官方解釋:http://msdn.microsoft.com/en-us/library/e0w9f63b(v=vs.80).aspx
舉例:reinterpret_cast用法
1 int main()2 {3 int a = 49;4 int *pi = &a;5 char *pc = reinterpret_cast<char*>(pi);//int * 到char *,用戶自己安全6 cout<<*pc<<endl; //輸出字符"1"7 unsigned long b = reinterpret_cast<unsigned long>(pc);//char * 轉(zhuǎn) unsigned long8 cout<<b<<endl;//輸出pc指向地址(即a的地址)對應的整數(shù)9 int *pi2 = reinterpret_cast<int *>(b);//unsigned long 轉(zhuǎn) int* 10 cout<<*pi2<<endl; //輸出49 11 }【4】const_cast?
用法:const_cast<type-id> (exdivssion)
該運算符用來修改類型的const、volatile、__unaligned屬性。除了const 、volatile、__unaligned修飾之外, type_id和exdivssion的類型是一樣的。
常量指針被轉(zhuǎn)化成非常量指針,并且仍然指向原來的對象;
常量引用被轉(zhuǎn)換成非常量引用,并且仍然指向原來的對象;常量對象被轉(zhuǎn)換成非常量對象。
msdn官方解釋:http://msdn.microsoft.com/en-us/library/bz6at95h(v=vs.80).aspx
舉例:const_cast用法
1 int main() 2 { 3 const int a = 100; 4 int *b = const_cast<int *>(&a);//const int * 轉(zhuǎn)int * 5 cout<<*b<<endl; //輸出100 6 cout<<&a<<" "<<b<<endl; //兩者值相同,表明b指向a的地址,只是const屬性變了 7 }
總結(jié):
類指針或引用的上行轉(zhuǎn)換static_cast 和 dynamic_cast 都可以
類指針或引用的下行轉(zhuǎn)換用dynamic_cast并且判斷轉(zhuǎn)換后是否為空
基本數(shù)據(jù)類型之間的轉(zhuǎn)換用static_cast, 但是由于數(shù)值范圍的不同,需要用戶保證轉(zhuǎn)換的安全性
不同類型之間的指針或引用的轉(zhuǎn)換用reinterpret_cast,它的本質(zhì)是對指向內(nèi)存的比特位的重解釋
消除數(shù)據(jù)的const、volatile、__unaligned屬性,用const_cast
【版權(quán)聲明】轉(zhuǎn)載請注明出處?http://www.cnblogs.com/TenosDoIt/p/3175217.html
轉(zhuǎn)載于:https://www.cnblogs.com/glllvwcc/p/5051393.html
總結(jié)
以上是生活随笔為你收集整理的c++ 数据类型转换: static_cast dynamic_cast reinterpret_cast const_cast的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: MASM32 Editor的使用
- 下一篇: 微信多开~