C++的四種類型轉(zhuǎn)換
一、隱式類型轉(zhuǎn)換和顯示類型轉(zhuǎn)換
當(dāng)?shù)忍杻蛇叺念愋筒煌臅r(shí)候、形參與實(shí)參類型不匹配的時(shí)候、返回值類型與接收返回值類型不一致時(shí),就需要發(fā)生類型轉(zhuǎn)化。
而類型轉(zhuǎn)換又分為隱式類型轉(zhuǎn)換和顯示類型轉(zhuǎn)換。
int main()
{
// 隱式類型轉(zhuǎn)換
int Ival = 1;
double Dval = Ival;
// 顯示類型轉(zhuǎn)換
int* p = &Ival;
int pi = p;// error
int pi = (int)p;
return 0;
}
隱式類型轉(zhuǎn)換是編譯器在編譯階段自動進(jìn)行,能轉(zhuǎn)就轉(zhuǎn),不能轉(zhuǎn)就編譯失敗。
而顯示類型轉(zhuǎn)換就要我們自己處理。
二、C++的四種類型轉(zhuǎn)換
上面的兩種類型轉(zhuǎn)換是C語言風(fēng)格的,存在一些缺點(diǎn)。
隱式類型轉(zhuǎn)換會造成精度的丟失。
而顯示類型轉(zhuǎn)換則會導(dǎo)致轉(zhuǎn)換不清晰(不知道誰轉(zhuǎn)化過來)。
所以C++提供了規(guī)范的四種類型轉(zhuǎn)換
2.1 static_cast 相似轉(zhuǎn)化
如果想要進(jìn)行相似類型的轉(zhuǎn)換,編譯器隱式執(zhí)行的任何類型轉(zhuǎn)換都可用。
但是如果是兩個(gè)不相關(guān)的類型就不能轉(zhuǎn)換。
int main()
{
int i = 0;
double d = static_cast<int>(i);
int* p = nullptr;
int pi = static_cast<int>(p);// error
return 0;
}
2.2 reinterpret_cast 不同類型轉(zhuǎn)化
上面我們用指針類型轉(zhuǎn)化成整型出現(xiàn)錯誤,而這種不同類型的轉(zhuǎn)換要用reinterpret_cast。
int main()
{
int i = 0;
double d = static_cast<int>(i);
int* p = nullptr;
int pi = static_cast<int>(p);// error
int pi = reinterpret_cast<int>(p);// correct
return 0;
}
2.3 const_cast 去除const屬性
使用const_cast的主要目的是為了去除一個(gè)const變量的const,方便賦值。
int main()
{
const int i = 1;
int* p = const_cast<int*>(&i);
*p = 3;
cout << i << endl;
return 0;
}
這里的結(jié)果需要注意一下:


這里是因?yàn)榫幾g器把這個(gè)變量放到了寄存器中,我們修改的是內(nèi)存中的數(shù)據(jù),不影響寄存器,我們可以加上volatile關(guān)鍵字(每次都去內(nèi)存中?。﹣砜纯矗?/p>
int main()
{
volatile const int i = 1;
int* p = const_cast<int*>(&i);
*p = 3;
cout << i << endl;
return 0;
}

2.4 dynamic_cast 向下轉(zhuǎn)換
dynamic_cast用于將一個(gè)父類對象的指針/引用轉(zhuǎn)換為子類對象的指針或引用(動態(tài)轉(zhuǎn)換)
在前面的文章【C++】繼承中講過,子類對象賦值給父類 對象/指針/引用,這里有個(gè)形象的說法叫切片或者切割,寓意把派生類中父類那部分切來賦值過去。
但是如果我們直接把父類類傳遞給子類,會不安全,因?yàn)楦割愞D(zhuǎn)給子類會多開一份空間,可能會越界訪問。
class A
{
public:
virtual void f() {}
public:
int _a = 0;
};
class B : public A
{
public:
int _b = 0;
};
void fun(A* pa)
{
B* pb = (B*)pa;
pb->_a++;
pb->_b++;
}
int main()
{
A a;
B b;
fun(&a);
fun(&b);
return 0;
}

而加上dynamic_cast后如果轉(zhuǎn)化失敗就會返回空指針,讓我們檢查:
class A
{
public:
virtual void f() {}
public:
int _a = 0;
};
class B : public A
{
public:
int _b = 0;
};
void fun(A* pa)
{
B* pb = dynamic_cast<B*>(pa);
cout << pb << endl;
if (pb)
{
pb->_a++;
pb->_b++;
}
}
int main()
{
A a;
B b;
fun(&a);
fun(&b);
return 0;
}

但是這里要注意dynamic_cast只能用于父類含有虛函數(shù)的類
到此這篇關(guān)于C++的四種類型轉(zhuǎn)換的文章就介紹到這了,更多相關(guān)C++類型轉(zhuǎn)換內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
C++找出字符串中出現(xiàn)最多的字符和次數(shù),時(shí)間復(fù)雜度小于O(n^2)
今天小編就為大家分享一篇關(guān)于C++找出字符串中出現(xiàn)最多的字符和次數(shù),時(shí)間復(fù)雜度小于O(n^2),小編覺得內(nèi)容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來看看吧2018-12-12
基于Matlab實(shí)現(xiàn)多目標(biāo)粘液霉菌算法的示例代碼
多目標(biāo)粘液霉菌算法(MOSMA),這是最近開發(fā)的粘液霉菌算法(SMA)的多目標(biāo)變體,用于處理工業(yè)中的多目標(biāo)優(yōu)化問題。本文將用Matlab實(shí)現(xiàn)這一算法,需要的可以參考一下2022-05-05
C++如何通過ostringstream實(shí)現(xiàn)任意類型轉(zhuǎn)string
再使用整型轉(zhuǎn)string的時(shí)候感覺有點(diǎn)棘手,因?yàn)閕toa不是標(biāo)準(zhǔn)C里面的,而且即便是有itoa,其他類型轉(zhuǎn)string不是很方便。后來去網(wǎng)上找了一下,發(fā)現(xiàn)有一個(gè)好方法2013-09-09
c++ 連接兩個(gè)字符串實(shí)現(xiàn)代碼 實(shí)現(xiàn)類似strcat功能
c++ 連接兩個(gè)字符串實(shí)現(xiàn)代碼 實(shí)現(xiàn)類似strcat功能,需要的朋友可以參考下2012-05-05
在Visual Studio 2019中修改項(xiàng)目名的方法
這篇文章主要介紹了在Visual Studio 2019中修改項(xiàng)目名的方法,文中通過示例介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-03-03
matlab鳥群算法求解車間調(diào)度問題詳解及實(shí)現(xiàn)源碼
這篇文章主要為大家介紹了matlab鳥群算法求解車間調(diào)度的問題分析及實(shí)現(xiàn)源碼,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步2022-02-02
OpenCV基于距離變換和分水嶺實(shí)現(xiàn)圖像分割
圖像分割是根據(jù)灰度、顏色、紋理和形狀等特征,把圖像分成若干個(gè)特定的、具有獨(dú)特性質(zhì)的區(qū)域。本文將基于距離變換和分水嶺實(shí)現(xiàn)圖像分割,需要的可以了解一下2022-09-09

