[初學(xué)C++]四種強(qiáng)制類型轉(zhuǎn)換

1) static_cast<類型說明符> (變量或表達(dá)式)

在C++語言中static_cast用于數(shù)據(jù)類型的強(qiáng)制轉(zhuǎn)換趟妥,強(qiáng)制將一種數(shù)據(jù)類型轉(zhuǎn)換為另一種數(shù)據(jù)類型。例如將整型數(shù)據(jù)轉(zhuǎn)換為浮點(diǎn)型數(shù)據(jù)。
它主要有如下幾種用法:

  1. 用于類層次結(jié)構(gòu)中基類和派生類之間指針或引用的轉(zhuǎn)換
    進(jìn)行上行轉(zhuǎn)換(把派生類的指針或引用轉(zhuǎn)換成基類表示)是安全的
    進(jìn)行下行轉(zhuǎn)換(把基類的指針或引用轉(zhuǎn)換為派生類表示)由于沒有動(dòng)態(tài)類型檢查蜀漆,是不安全的
  2. 用于基本數(shù)據(jù)類型之間的轉(zhuǎn)換虾攻,如把int轉(zhuǎn)換成char。這種轉(zhuǎn)換的安全也要開發(fā)人員來保證
  3. 把空指針轉(zhuǎn)換成目標(biāo)類型的空指針
  4. 把任何類型的表達(dá)式轉(zhuǎn)換為void類型
  • 注意:static_cast不能轉(zhuǎn)換掉expression的const框都、volitale或者_(dá)_unaligned屬性搬素。
  • static_cast:可以實(shí)現(xiàn)C++中內(nèi)置基本數(shù)據(jù)類型之間的相互轉(zhuǎn)換。
  • 如果涉及到類的話魏保,static_cast只能在有相互聯(lián)系的類型中進(jìn)行相互轉(zhuǎn)換,不一定包含虛函數(shù)熬尺。

2) const_cast<類型說明符> (變量或表達(dá)式)

const_cast用于強(qiáng)制去掉const這種不能被修改的常數(shù)特性,但需要特別注意的是const_cast不是用于去除變量的常量性谓罗,而是去除指向常數(shù)對(duì)象的指針或引用的常量性粱哼,其去除常量性的對(duì)象必須為指針或引用。

用法:const_cast<type_id> (expression)
該運(yùn)算符用來修改類型的const或volatile屬性檩咱。除了const 或volatile修飾之外揭措, type_id和expression的類型是一樣的。

常量指針被轉(zhuǎn)化成非常量指針刻蚯,并且仍然指向原來的對(duì)象绊含;
常量引用被轉(zhuǎn)換成非常量引用,并且仍然指向原來的對(duì)象炊汹;
常量對(duì)象被轉(zhuǎn)換成非常量對(duì)象艺挪。

下面代碼,變量a一開始就被聲明為一個(gè)常量變量兵扬,不管后面的程序怎么處理麻裳,它就是一個(gè)常量,就是不會(huì)變化的器钟。我們稱“*q=20”語句為未定義行為語句津坑,所謂的未定義行為是指在標(biāo)準(zhǔn)的C++規(guī)范中并沒有明確規(guī)定這種語句的具體行為,該語句的具體行為由編譯器來自行決定如何處理傲霸。對(duì)于這種未定義行為的語句我們應(yīng)該盡量予以避免疆瑰!
了解了const_cast的使用場(chǎng)景后眉反,可以知道使用const_cast通常是一種無奈之舉,同時(shí)也建議大家在今后的C++程序設(shè)計(jì)過程中一定不要利用const_cast去掉指針或引用的常量性并且去修改原始變量的數(shù)值穆役,這是一種非常不好的行為寸五。

int main()
{
    const int a = 10;
    const int * p = &a;
    int *q =const_cast<int *>(p);
    *q = 20;    //fine
    cout <<a<<" "<<*p<<" "<<*q<<endl;//a=10 *p=20 *q=20
    return 0;
}

3) reinterpret_cast<類型說明符> (變量或表達(dá)式)

在C++語言中,reinterpret_cast主要有三種強(qiáng)制轉(zhuǎn)換用途:
改變指針或引用的類型耿币、將指針或引用轉(zhuǎn)換為一個(gè)足夠長(zhǎng)度的整形梳杏、將整型轉(zhuǎn)換為指針或引用類型。

用法:reinterpret_cast<type_id> (expression)
type-id必須是一個(gè)指針淹接、引用十性、算術(shù)類型、函數(shù)指針或者成員指針塑悼。
它可以把一個(gè)指針轉(zhuǎn)換成一個(gè)整數(shù)劲适,也可以把一個(gè)整數(shù)轉(zhuǎn)換成一個(gè)指針(先把一個(gè)指針轉(zhuǎn)換成一個(gè)整數(shù),在把該整數(shù)轉(zhuǎn)換成原類型的指針厢蒜,還可以得到原先的指針值)霞势。
在使用reinterpret_cast強(qiáng)制轉(zhuǎn)換過程僅僅只是比特位的拷貝,因此在使用過程中需要特別謹(jǐn)慎斑鸦!
int *a = new int;
double *d = reinterpret_cast<double *>(a);
上栗子中愕贡,將整型指針通過reinterpret_cast強(qiáng)制轉(zhuǎn)換成了雙精度浮點(diǎn)型指針。
reinterpret_cast可以將指針或引用轉(zhuǎn)換為一個(gè)足夠長(zhǎng)度的整形鄙才,此中的足夠長(zhǎng)度具體長(zhǎng)度需要多少則取決于操作系統(tǒng)颂鸿,如果是32位的操作系統(tǒng)促绵,就需要4個(gè)字節(jié)及以上的整型攒庵,如果是64位的操作系統(tǒng)則需要8個(gè)字節(jié)及以上的整型。

4) dynamic_cast

用法:dynamic_cast<type_id> (expression)

  1. 其他三種都是編譯時(shí)完成的败晴,dynamic_cast是運(yùn)行時(shí)處理的浓冒,運(yùn)行時(shí)要進(jìn)行類型檢查。
  2. 不能用于內(nèi)置的基本數(shù)據(jù)類型的強(qiáng)制轉(zhuǎn)換尖坤。
  3. dynamic_cast轉(zhuǎn)換如果成功的話返回的是指向類的指針或引用稳懒,轉(zhuǎn)換失敗的話則會(huì)返回NULL。
  4. 使用dynamic_cast進(jìn)行轉(zhuǎn)換的慢味,基類中一定要有虛函數(shù)场梆,否則編譯不通過。
    B中需要檢測(cè)有虛函數(shù)的原因:類中存在虛函數(shù)纯路,就說明它有想要讓基類指針或引用指向派生類對(duì)象的情況或油,此時(shí)轉(zhuǎn)換才有意義。
    這是由于運(yùn)行時(shí)類型檢查需要運(yùn)行時(shí)類型信息驰唬,而這個(gè)信息存儲(chǔ)在類的虛函數(shù)表(關(guān)于虛函數(shù)表的概念顶岸,詳細(xì)可見<Inside c++ object model>)中腔彰,
    只有定義了虛函數(shù)的類才有虛函數(shù)表。
  5. 在類的轉(zhuǎn)換時(shí)辖佣,在類層次間進(jìn)行上行轉(zhuǎn)換時(shí)霹抛,dynamic_cast和static_cast的效果是一樣的。在進(jìn)行下行轉(zhuǎn)換時(shí)卷谈,dynamic_cast具有類型檢查的功能杯拐,比static_cast更安全。
  • 向上轉(zhuǎn)換雏搂,即為子類指針指向父類指針(一般不會(huì)出問題)藕施;向下轉(zhuǎn)換,即將父類指針轉(zhuǎn)化子類指針凸郑。
  • 向下轉(zhuǎn)換的成功與否還與將要轉(zhuǎn)換的類型有關(guān)裳食,即要轉(zhuǎn)換的指針指向的對(duì)象的實(shí)際類型與轉(zhuǎn)換以后的對(duì)象類型一定要相同,否則轉(zhuǎn)換失敗芙沥。
  • 在C++中诲祸,編譯期的類型轉(zhuǎn)換有可能會(huì)在運(yùn)行時(shí)出現(xiàn)錯(cuò)誤,特別是涉及到類對(duì)象的指針或引用操作時(shí)而昨,更容易產(chǎn)生錯(cuò)誤救氯。Dynamic_cast操作符則可以在運(yùn)行期對(duì)可能產(chǎn)生問題的類型轉(zhuǎn)換進(jìn)行測(cè)試。
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末歌憨,一起剝皮案震驚了整個(gè)濱河市着憨,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌务嫡,老刑警劉巖甲抖,帶你破解...
    沈念sama閱讀 210,914評(píng)論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異心铃,居然都是意外死亡准谚,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,935評(píng)論 2 383
  • 文/潘曉璐 我一進(jìn)店門去扣,熙熙樓的掌柜王于貴愁眉苦臉地迎上來柱衔,“玉大人,你說我怎么就攤上這事愉棱∷纛恚” “怎么了?”我有些...
    開封第一講書人閱讀 156,531評(píng)論 0 345
  • 文/不壞的土叔 我叫張陵奔滑,是天一觀的道長(zhǎng)艾岂。 經(jīng)常有香客問我,道長(zhǎng)档押,這世上最難降的妖魔是什么澳盐? 我笑而不...
    開封第一講書人閱讀 56,309評(píng)論 1 282
  • 正文 為了忘掉前任祈纯,我火速辦了婚禮,結(jié)果婚禮上叼耙,老公的妹妹穿的比我還像新娘腕窥。我一直安慰自己,他們只是感情好筛婉,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,381評(píng)論 5 384
  • 文/花漫 我一把揭開白布簇爆。 她就那樣靜靜地躺著,像睡著了一般爽撒。 火紅的嫁衣襯著肌膚如雪入蛆。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,730評(píng)論 1 289
  • 那天硕勿,我揣著相機(jī)與錄音哨毁,去河邊找鬼。 笑死源武,一個(gè)胖子當(dāng)著我的面吹牛扼褪,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播粱栖,決...
    沈念sama閱讀 38,882評(píng)論 3 404
  • 文/蒼蘭香墨 我猛地睜開眼话浇,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了闹究?” 一聲冷哼從身側(cè)響起幔崖,我...
    開封第一講書人閱讀 37,643評(píng)論 0 266
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎渣淤,沒想到半個(gè)月后赏寇,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,095評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡砂代,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,448評(píng)論 2 325
  • 正文 我和宋清朗相戀三年蹋订,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了率挣。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片刻伊。...
    茶點(diǎn)故事閱讀 38,566評(píng)論 1 339
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖椒功,靈堂內(nèi)的尸體忽然破棺而出捶箱,到底是詐尸還是另有隱情,我是刑警寧澤动漾,帶...
    沈念sama閱讀 34,253評(píng)論 4 328
  • 正文 年R本政府宣布丁屎,位于F島的核電站,受9級(jí)特大地震影響旱眯,放射性物質(zhì)發(fā)生泄漏晨川。R本人自食惡果不足惜证九,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,829評(píng)論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望共虑。 院中可真熱鬧愧怜,春花似錦、人聲如沸妈拌。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,715評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)尘分。三九已至猜惋,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間培愁,已是汗流浹背著摔。 一陣腳步聲響...
    開封第一講書人閱讀 31,945評(píng)論 1 264
  • 我被黑心中介騙來泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留定续,地道東北人梨撞。 一個(gè)月前我還...
    沈念sama閱讀 46,248評(píng)論 2 360
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像香罐,于是被迫代替她去往敵國(guó)和親卧波。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,440評(píng)論 2 348

推薦閱讀更多精彩內(nèi)容