青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

asm, c, c++ are my all
-- Core In Computer
posts - 139,  comments - 123,  trackbacks - 0

static_cast<>揭密


作者:Sam NG

譯者: 小刀人


原文鏈接: What static_cast<> is actually doing?

本文討論static_cast<> 和 reinterpret_cast<>。

介紹
大多程序員在學(xué)C++前都學(xué)過C,并且習(xí)慣于C風(fēng)格(類型)轉(zhuǎn)換。當(dāng)寫C++(程序)時,有時候我們在使用static_cast<>和reinterpret_cast<>時可能會有點模糊。在本文中,我將說明static_cast<>實際上做了什么,并且指出一些將會導(dǎo)致錯誤的情況。

泛型(Generic Types)

??????? float f = 12.3;
??????? float* pf = &f;
??????? // static cast<>
??????? // 成功編譯, n = 12
??????? int n = static_cast<int>(f);
??????? // 錯誤,指向的類型是無關(guān)的(譯注:即指針變量pf是float類型,現(xiàn)在要被轉(zhuǎn)換為int類型)
??????? //int* pn = static_cast<int*>(pf);
??????? //成功編譯
??????? void* pv = static_cast<void*>(pf);
??????? //成功編譯, 但是 *pn2是無意義的內(nèi)存(rubbish)
??????? int* pn2 = static_cast<int*>(pv);// reinterpret_cast<>
??????? //錯誤,編譯器知道你應(yīng)該調(diào)用static_cast<>
??????? //int i = reinterpret_cast<int>(f);
??????? //成功編譯, 但是 *pn 實際上是無意義的內(nèi)存,和 *pn2一樣
??????? int* pi = reinterpret_cast<int*>(pf);
簡而言之,static_cast<> 將嘗試轉(zhuǎn)換,舉例來說,如float-到-integer,而reinterpret_cast<>簡單改變編譯器的意圖重新考慮那個對象作為另一類型。

指針類型(Pointer Types)

指針轉(zhuǎn)換有點復(fù)雜,我們將在本文的剩余部分使用下面的類:

class CBaseX
????? {
????? public:
????? int x;
????? CBaseX() { x = 10; }
????? void foo() { printf("CBaseX::foo() x=%d\n", x); }
????? };
????? class CBaseY
??????? {
??????? public:
??????? int y;
??????? int* py;
??????? CBaseY() { y = 20; py = &y; }
??????? void bar() { printf("CBaseY::bar() y=%d, *py=%d\n", y, *py);
??????? }
??????? };class CDerived : public CBaseX, public CBaseY
??????? {
??????? public:
??????? int z;
??????? };
情況1:兩個無關(guān)的類之間的轉(zhuǎn)換

????? // Convert between CBaseX* and CBaseY*
????? // CBaseX* 和 CBaseY*之間的轉(zhuǎn)換
????? CBaseX* pX = new CBaseX();
????? // Error, types pointed to are unrelated
????? // 錯誤, 類型指向是無關(guān)的
????? // CBaseY* pY1 = static_cast<CBaseY*>(pX);
????? // Compile OK, but pY2 is not CBaseX
????? // 成功編譯, 但是 pY2 不是CBaseX
????? CBaseY* pY2 = reinterpret_cast<CBaseY*>(pX);
????? // System crash!!
????? // 系統(tǒng)崩潰!!
????? // pY2->bar();
正如我們在泛型例子中所認(rèn)識到的,如果你嘗試轉(zhuǎn)換一個對象到另一個無關(guān)的類static_cast<>將失敗,而reinterpret_cast<>就總是成功“欺騙”編譯器:那個對象就是那個無關(guān)類。

情況2:轉(zhuǎn)換到相關(guān)的類

????? 1. CDerived* pD = new CDerived();
????? 2. printf("CDerived* pD = %x\n", (int)pD);
????? 3.
????? 4. // static_cast<> CDerived* -> CBaseY* -> CDerived*
????? //成功編譯,隱式static_cast<>轉(zhuǎn)換
????? 5. CBaseY* pY1 = pD;
????? 6. printf("CBaseY* pY1 = %x\n", (int)pY1);
????? // 成功編譯, 現(xiàn)在 pD1 = pD
????? 7. CDerived* pD1 = static_cast<CDerived*>(pY1);
????? 8. printf("CDerived* pD1 = %x\n", (int)pD1);
????? 9.
????? 10. // reinterpret_cast
????? // 成功編譯, 但是 pY2 不是 CBaseY*
????? 11. CBaseY* pY2 = reinterpret_cast<CBaseY*>(pD);
????? 12. printf("CBaseY* pY2 = %x\n", (int)pY2);
????? 13.
????? 14. // 無關(guān)的 static_cast<>
????? 15. CBaseY* pY3 = new CBaseY();
????? 16. printf("CBaseY* pY3 = %x\n", (int)pY3);
????? // 成功編譯,盡管 pY3 只是一個 "新 CBaseY()"
????? 17. CDerived* pD3 = static_cast<CDerived*>(pY3);
????? 18. printf("CDerived* pD3 = %x\n", (int)pD3);
????? ---------------------- 輸出 ---------------------------
????? CDerived* pD = 392fb8
????? CBaseY* pY1 = 392fbc
????? CDerived* pD1 = 392fb8
????? CBaseY* pY2 = 392fb8
????? CBaseY* pY3 = 390ff0
????? CDerived* pD3 = 390fec
注意:在將CDerived*用隱式 static_cast<>轉(zhuǎn)換到CBaseY*(第5行)時,結(jié)果是(指向)CDerived*(的指針向后) 偏移了4(個字節(jié))(譯注:4為int類型在內(nèi)存中所占字節(jié)數(shù))。為了知道static_cast<> 實際如何,我們不得不要來看一下CDerived的內(nèi)存布局。
?

CDerived的內(nèi)存布局(Memory Layout)



如圖所示,CDerived的內(nèi)存布局包括兩個對象,CBaseX 和 CBaseY,編譯器也知道這一點。因此,當(dāng)你將CDerived* 轉(zhuǎn)換到 CBaseY*時,它給指針添加4個字節(jié),同時當(dāng)你將CBaseY*轉(zhuǎn)換到CDerived*時,它給指針減去4。然而,甚至它即便不是一個CDerived你也可以這樣做。

當(dāng)然,這個問題只在如果你做了多繼承時發(fā)生。在你將CDerived轉(zhuǎn)換 到 CBaseX時static_cast<> 和 reinterpret_cast<>是沒有區(qū)別的。

情況3:void*之間的向前和向后轉(zhuǎn)換

因為任何指針可以被轉(zhuǎn)換到void*,而void*可以被向后轉(zhuǎn)換到任何指針(對于static_cast<> 和 reinterpret_cast<>轉(zhuǎn)換都可以這樣做),如果沒有小心處理的話錯誤可能發(fā)生。

??????? CDerived* pD = new CDerived();
??????? printf("CDerived* pD = %x\n", (int)pD);
??????? CBaseY* pY = pD; // 成功編譯, pY = pD + 4
??????? printf("CBaseY* pY = %x\n", (int)pY);
??????? void* pV1 = pY; //成功編譯, pV1 = pY
??????? printf("void* pV1 = %x\n", (int)pV1);
??????? // pD2 = pY, 但是我們預(yù)期 pD2 = pY - 4
??????? CDerived* pD2 = static_cast<CDerived*>(pV1);
??????? printf("CDerived* pD2 = %x\n", (int)pD2);
??????? // 系統(tǒng)崩潰
??????? // pD2->bar();

??????? ---------------------- 輸出 ---------------------------
??????? CDerived* pD = 392fb8
??????? CBaseY* pY = 392fbc
??????? void* pV1 = 392fbc
??????? CDerived* pD2 = 392fbc

一旦我們已經(jīng)轉(zhuǎn)換指針為void*,我們就不能輕易將其轉(zhuǎn)換回原類。在上面的例子中,從一個void* 返回CDerived*的唯一方法是將其轉(zhuǎn)換為CBaseY*然后再轉(zhuǎn)換為CDerived*。
但是如果我們不能確定它是CBaseY* 還是 CDerived*,這時我們不得不用dynamic_cast<> 或typeid[2]。

注釋:
1. dynamic_cast<>,從另一方面來說,可以防止一個泛型CBaseY* 被轉(zhuǎn)換到CDerived*。
2. dynamic_cast<>需要類成為多態(tài),即包括“虛”函數(shù),并因此而不能成為void*。
參考:
1. [MSDN] C++ Language Reference -- Casting
2. Nishant Sivakumar, Casting Basics - Use C++ casts in your VC++.NET programs
3. Juan Soulie, C++ Language Tutorial: Type Casting

posted on 2006-05-23 01:45 Jerry Cat 閱讀(492) 評論(0)  編輯 收藏 引用

只有注冊用戶登錄后才能發(fā)表評論。
網(wǎng)站導(dǎo)航: 博客園   IT新聞   BlogJava   博問   Chat2DB   管理



<2006年5月>
30123456
78910111213
14151617181920
21222324252627
28293031123
45678910

常用鏈接

留言簿(7)

隨筆檔案

最新隨筆

搜索

  •  

最新評論

閱讀排行榜

評論排行榜

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            欧美在线高清视频| 亚洲激情偷拍| 久久精品视频一| 亚洲国产欧洲综合997久久| 一区二区三区色| 亚洲国产精品久久久久久女王| 欧美日本二区| 麻豆精品精品国产自在97香蕉| 欧美一区三区二区在线观看| 亚洲午夜日本在线观看| 日韩一级精品视频在线观看| 91久久夜色精品国产九色| 影音先锋久久| 欧美日韩久久| 欧美日韩中文在线观看| 欧美日韩国产不卡在线看| 免费成人在线视频网站| 久久九九热re6这里有精品| 在线午夜精品自拍| 一区二区三区四区五区视频| 一区二区免费在线播放| 国产偷国产偷亚洲高清97cao| 亚洲午夜视频在线| 一本一本a久久| 亚洲一区精品视频| 午夜久久一区| 亚洲综合日本| 久久久99免费视频| 欧美成人精品在线| 欧美日韩在线直播| 国产一区二区三区精品欧美日韩一区二区三区| 国产欧美日韩在线| 一区二区在线观看视频| 国产精品欧美久久久久无广告| 欧美视频一二三区| 国产日韩av一区二区| 精品av久久久久电影| 国产九区一区在线| 一区二区三区亚洲| 99国产精品久久久久久久成人热| 中文日韩在线视频| 久久久一本精品99久久精品66| 榴莲视频成人在线观看| 亚洲福利在线视频| 一区二区三区偷拍| 久久国产精品毛片| 亚洲欧洲精品一区二区| 亚洲精品免费网站| 亚洲自拍三区| 蜜桃av综合| 宅男噜噜噜66一区二区66| 亚洲视频免费在线观看| 久久久久久久综合日本| 欧美日产国产成人免费图片| 国产一区二区成人| 亚洲手机视频| 欧美jizz19性欧美| 亚洲专区在线| 欧美日韩国产综合视频在线观看| 国内外成人在线| 亚洲一区在线直播| 亚洲欧洲日韩综合二区| 久久精品视频在线| 国产精品羞羞答答| 一区二区三区精品久久久| 久久美女性网| 午夜久久久久| 国产精品少妇自拍| 亚洲欧洲日本在线| 欧美α欧美αv大片| 亚洲在线视频| 国产精品福利av| 夜夜嗨av一区二区三区中文字幕| 美玉足脚交一区二区三区图片| 亚洲精品四区| 欧美极品一区二区三区| 亚洲精选在线| 91久久精品久久国产性色也91 | 亚洲国产精品成人va在线观看| 亚洲欧美激情视频| 国产精品国产自产拍高清av王其| 亚洲精品久久久久久久久久久久久| 久久久久久久综合日本| 最新亚洲激情| 欧美日韩mv| 亚洲麻豆视频| 亚洲国产另类久久精品| 午夜免费久久久久| 国产日韩三区| 另类春色校园亚洲| 久久这里只精品最新地址| 亚洲第一中文字幕| 欧美影院精品一区| 欧美1区2区| 一区二区欧美视频| 亚洲系列中文字幕| 国产一区二区三区在线观看精品 | 欧美在线免费视屏| 亚洲一区三区在线观看| 国产精品久久久久影院色老大| 亚洲午夜日本在线观看| 一区二区三区欧美在线观看| 欧美色播在线播放| 欧美与欧洲交xxxx免费观看| 美女爽到呻吟久久久久| 日韩亚洲在线观看| 亚洲一区二区三区色| 国产欧美日韩精品一区| 久久久噜噜噜久久人人看| 久久久噜噜噜久久人人看| 亚洲三级免费电影| 亚洲一二三区在线观看| 伊伊综合在线| 亚洲区欧美区| 国产精品自拍网站| 欧美好吊妞视频| 国产精品久久久久77777| 久久精品国产亚洲a| 牛人盗摄一区二区三区视频| 亚洲一区二区三区在线看| 一二三区精品福利视频| 91久久在线| 欧美亚洲综合另类| aⅴ色国产欧美| 欧美诱惑福利视频| 一区二区国产日产| 久久久久国色av免费观看性色| 国产亚洲va综合人人澡精品| 欧美电影在线播放| 国产精品午夜春色av| 免费视频一区二区三区在线观看| 欧美日韩国产免费| 老司机午夜免费精品视频 | 欧美亚洲综合网| 欧美网站在线观看| 免费在线欧美黄色| 国产精品一区二区在线观看不卡 | 久久久久久久久久久久久久一区| 欧美精品二区| 免费在线观看精品| 国产一区二区三区久久悠悠色av| 99国产麻豆精品| 亚洲精品综合精品自拍| 久久久欧美精品sm网站| 久久福利精品| 国产精品日本精品| 99国产精品自拍| 艳妇臀荡乳欲伦亚洲一区| 欧美人与禽猛交乱配| 欧美国产乱视频| 娇妻被交换粗又大又硬视频欧美| 亚洲一本视频| 亚洲综合电影一区二区三区| 欧美精品在线观看91| 一区二区三区日韩欧美| 欧美韩日精品| 亚洲国产精品va| 亚洲经典在线看| 欧美精品在线观看91| 国内外成人免费激情在线视频网站| 日韩视频第一页| av成人激情| 欧美肉体xxxx裸体137大胆| 亚洲片在线资源| 免费久久99精品国产| 老司机午夜精品| 1024成人| 久久高清一区| 亚洲日本欧美| 亚洲欧美日韩国产成人| 国产精品国产精品| 亚洲一区二区免费在线| 性做久久久久久久久| 亚洲综合视频网| 亚洲第一区在线| 9i看片成人免费高清| 久久国产日韩欧美| 久久亚洲视频| 亚洲国产人成综合网站| 欧美精品色网| 亚洲专区一区| 你懂的视频一区二区| 亚洲国产一区二区三区在线播| 校园春色国产精品| 日韩午夜电影av| 欧美影院视频| 亚洲免费电影在线| 国产精品久久久久一区二区三区共| 亚洲一区二区在线视频| 欧美aaa级| 亚洲欧美三级伦理| 一区久久精品| 欧美日韩色一区| 久久成人人人人精品欧| 免费不卡视频| 亚洲一区黄色| 亚洲高清一二三区| 国产精品黄色在线观看| 久久99在线观看| 中文精品一区二区三区|