C++四种类型强制转换——const_cast、static_cast、dynamic_cast、reinterpret_cast
文章目錄
- 一、const_cast
- 1.基本知識
- 2.示例演示
- 二、static_cast
- 1.基本知識
- 2.示例演示
- 三、dynamic_cast
- 1.基本知識
- 2.示例演示
- 四、reinterpret_cast
一、const_cast
1.基本知識
(1)const_cast只針對指針、引用,當然,this指針也是其中之一。
(2)const_cast的大部分使用主要是將常量指針轉換為常指針。常量指針指向的空間的內容不允許被修改,但是使用const_cast進行強制轉換就可以修改。
(3)const_cast只能調節類型限定符,不能修改基本類型。在普通指針演示中給出示例。
2.示例演示
(1)普通指針
用代碼演示:
(2)引用
int main() {int a = 10;const int& b = a;//b = 20;//錯誤原因:常量引用,不允許修改值//int& c = b;//錯誤,和常量指針不允許給普通指針賦值或者初始化一樣int& c = const_cast<int&>(b);c = 20;cout << a << endl;//20const_cast<int&>(b) = 30;cout << a << endl;//30return 0; }(3)this指針
class Test { public:Test() {}void fun()const//此時this指針相當于const Test* const this{//this->val1 = 10;//錯誤const_cast<Test*>(this)->val1 = 10;//OK} private:int val1;int val2; };二、static_cast
1.基本知識
(1)static_cast的使用基本等價于隱式轉換的一種類型轉化運算符,可使用于需要明確隱式轉換的地方。就相當于把隱式轉換給明確寫了出來而已。
(2)可以用于低風險的轉換
什么叫低風險的轉化,一般只要編譯器能自己進行隱式轉換的都是低風險轉換,一般平等轉換和提升轉換都是低風險的轉換。比如以下幾種情況:
①整形和浮點型
②字符與整形
③轉換運算符
④空指針轉換為任何目標類型的指針
(3)不可以用于風險較高的轉換
①不同類型的指針之間互相轉換
②非指針類型和指針類型之間的相互轉換
③不同類型的引用之間的轉換
2.示例演示
class Base { public:Base() {}~Base() {} }; class Son:public Base { public:Son() {}~Son() {} };int main() {char c_a = 0;int i_a = 0;float f_a = 0;double d_a = 1.111111;void* v_ptr = NULL;int* i_ptr = new int(1);char* c_ptr = new char(1);//下面部分沒有報錯,可以運行,但是平時不允許這樣寫,除非自己很明確自己在干什么//從高字節數到低字節數的轉換平常肯定是不允許這樣用的,因為將一個多字節的內容轉換到少字節,非常容易丟失數據char c_sc = static_cast<char>(i_a);c_sc = static_cast<char>(f_a);c_sc = static_cast<char>(d_a);//類似于下面的轉換不允許,因為兩個不同的指針類型之間不允許相互轉換//int* i_scptr = static_cast<int*>(c_ptr);//報錯//下面的指針類型轉換允許int* i_scptr = static_cast<int*>(v_ptr);void* v_scptr = static_cast<void*>(i_ptr);//下面的可取,只不過有時候精度可能會降低而已,比如float轉換為int,被視為低風險float f_sc = static_cast<float>(i_a);int i_sc = static_cast<int>(c_a);cout << i_sc << endl;//父類指針和派生類指針的指向問題Base* bptr1 = new Base();Son* sptr1 = new Son();Base* bptr;Son* sptr;bptr = new Son(); //語句1 正確,基類指針指向派生類實體//sptr = new Base();//語句2 錯誤,派生類指針指向父類bptr = static_cast<Base*>(sptr1);//等同于語句1,正確sptr = static_cast<Son*>(bptr1); //等同于語句2,但是不安全,平時使用也不會使派生類指針指向基類,會出現訪問越界,有時候會崩潰,有時候我們卻沒辦法發現//對于派生類指針指向基類,會用另一個強制轉換dynamic_castreturn 0; }三、dynamic_cast
1.基本知識
(1)用于具有虛函數的基類與派生類之間的指針或引用的轉換。
(2)基類必須具有虛函數。dynamic_cast是運行時類型信息(RTTI),而這個信息是存儲與類的虛函數表關系緊密的信息,只有一個類定義了虛函數,才會有虛函數表。
運行時檢查,轉型不成功則返回一個空指針
非必要不使用dynamic_cast,因為有額外的開銷。
(3)常用的轉換方式
基類指針或引用轉派生類指針(必須使用dynamic_cast)
派生類指針或引用轉基類指針(可以使用dynamic_cast,但是更推薦用static_cast)
2.示例演示
在這里只演示必須使用dynamic_cast的情況。(注意,基類必須有虛函數)
class Base { public:Base() { b_val = 1; }~Base() {}virtual void fun() {}int b_val; };class Son :public Base { public:Son() { s_val = 2; }~Son() {}int s_val; };int main() {Base* b_ptr = new Base();Son* s_ptr = dynamic_cast<Son*>(b_ptr);return 0; }調試可以發現,s_ptr為NULL,轉換不成功。因為代碼運行時,dynamic_static轉換時進行了運行時安全檢查,檢查了被轉換的指針的類型,和轉換成的指針的類型,發現不安全,就會轉換失敗,返回空指針。
四、reinterpret_cast
這個和C語言的強制轉換沒什么區別,只不過C++用自己的寫法替代了C語言的強制轉換而已。
①不同類型的指針之間的轉換
②指針和能容納指針的整數類型之間的轉換(比如將int類型強轉成int*類型)
③不同類型的引用之間的轉換
編譯期處理執行的是逐字節復制的操作。
類似于強制轉換,至于強制轉換會產生什么后果需要自己承擔。
由于和C語言的強制轉換一樣,這里不進行贅述。
總結
以上是生活随笔為你收集整理的C++四种类型强制转换——const_cast、static_cast、dynamic_cast、reinterpret_cast的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Shell——常用工具(cut、sed、
- 下一篇: Lua——基本语法知识,从hello w