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

洗塵齋

三懸明鏡垂鴻韻,九撩清泉洗塵心

常用鏈接

統(tǒng)計

最新評論

C++風格的類型轉換的用法(ZZ)

C++風格的類型轉換的用法

這是More Effecitve C++里的第二條對類型轉換講的很好,也很基礎好懂。
Item M2:盡量使用C++風格的類型轉換
仔細想想地位卑賤的類型轉換功能(cast),其在程序設計中的地位就象goto語句一樣令人鄙視。但是它還不是無法令人忍受,因為當在某些緊要的關頭,類型轉換還是必需的,這時它是一個必需品。
不過C風格的類型轉換并不代表所有的類型轉換功能。
一 來它們過于粗魯,能允許你在任何類型之間進行轉換。不過如果要進行更精確的類型轉換,這會是一個優(yōu)點。在這些類型轉換中存在著巨大的不同,例如把一個指向 const對象的指針(pointer-to-const-object)轉換成指向非const對象的指針(pointer-to-non-const -object)(即一個僅僅去除const的類型轉換),把一個指向基類的指針轉換成指向子類的指針(即完全改變對象類型)。傳統(tǒng)的C風格的類型轉換不 對上述兩種轉換進行區(qū)分。(這一點也不令人驚訝,因為C風格的類型轉換是為C語言設計的,而不是為C++語言設計的)。
二來C風格的類型轉換在程 序語句中難以識別。在語法上,類型轉換由圓括號和標識符組成,而這些可以用在C++中的任何地方。這使得回答象這樣一個最基本的有關類型轉換的問題變得很 困難:“在這個程序中是否使用了類型轉換?”。這是因為人工閱讀很可能忽略了類型轉換的語句,而利用象grep的工具程序也不能從語句構成上區(qū)分出它們 來。
C++通過引進四個新的類型轉換操作符克服了C風格類型轉換的缺點,這四個操作符是, static_cast, const_cast, dynamic_cast, 和reinterpret_cast。在大多數(shù)情況下,對于這些操作符你只需要知道原來你習慣于這樣寫,
(type) expression
而現(xiàn)在你總應該這樣寫:
static_cast<type>(expression)
例如,假設你想把一個int轉換成double,以便讓包含int類型變量的表達式產(chǎn)生出浮點數(shù)值的結果。如果用C風格的類型轉換,你能這樣寫:
int firstNumber, secondNumber;
...
double result = ((double)firstNumber)/secondNumber;
如果用上述新的類型轉換方法,你應該這樣寫:
double result = static_cast<double>(firstNumber)/secondNumber;
這樣的類型轉換不論是對人工還是對程序都很容易識別。
static_cast 在功能上基本上與C風格的類型轉換一樣強大,含義也一樣。它也有功能上限制。例如,你不能用static_cast象用C風格的類型轉換一樣把 struct轉換成int類型或者把double類型轉換成指針類型,另外,static_cast不能從表達式中去除const屬性,因為另一個新的類 型轉換操作符const_cast有這樣的功能。
其它新的C++類型轉換操作符被用在需要更多限制的地方。const_cast用于類型轉換掉表 達式的const或volatileness屬性。通過使用const_cast,你向人們和編譯器強調(diào)你通過類型轉換想做的只是改變一些東西的 constness或者volatileness屬性。這個含義被編譯器所約束。如果你試圖使用const_cast來完成修改constness 或者volatileness屬性之外的事情,你的類型轉換將被拒絕。下面是一些例子:
class Widget { ... };
class SpecialWidget: public Widget { ... };
void update(SpecialWidget *psw);
SpecialWidget sw; // sw 是一個非const 對象。
const SpecialWidget& csw = sw; // csw 是sw的一個引用
// 它是一個const 對象
update(&csw); // 錯誤!不能傳遞一個const SpecialWidget* 變量
// 給一個處理SpecialWidget*類型變量的函數(shù)
update(const_cast<SpecialWidget*>(&csw));
// 正確,csw的const被顯示地轉換掉(
// csw和sw兩個變量值在update
//函數(shù)中能被更新)
update((SpecialWidget*)&csw);
// 同上,但用了一個更難識別
//的C風格的類型轉換
Widget *pw = new SpecialWidget;
update(pw); // 錯誤!pw的類型是Widget*,但是
// update函數(shù)處理的是SpecialWidget*類型
update(const_cast<SpecialWidget*>(pw));
// 錯誤!const_cast僅能被用在影響
// constness or volatileness的地方上。,
// 不能用在向繼承子類進行類型轉換。
到目前為止,const_cast最普通的用途就是轉換掉對象的const屬性。
第 二種特殊的類型轉換符是dynamic_cast,它被用于安全地沿著類的繼承關系向下進行類型轉換。這就是說,你能用dynamic_cast把指向基 類的指針或引用轉換成指向其派生類或其兄弟類的指針或引用,而且你能知道轉換是否成功。失敗的轉換將返回空指針(當對指針進行類型轉換時)或者拋出異常 (當對引用進行類型轉換時):
Widget *pw;
...
update(dynamic_cast<SpecialWidget*>(pw));
// 正確,傳遞給update函數(shù)一個指針
// 是指向變量類型為SpecialWidget的pw的指針
// 如果pw確實指向一個對象,
// 否則傳遞過去的將使空指針。
void updateViaRef(SpecialWidget& rsw);
updateViaRef(dynamic_cast<SpecialWidget&>(*pw));
//正確。傳遞給updateViaRef函數(shù)
// SpecialWidget pw 指針,如果pw
// 確實指向了某個對象
// 否則將拋出異常
dynamic_casts在幫助你瀏覽繼承層次上是有限制的。它不能被用于缺乏虛函數(shù)的類型上(參見條款M24),也不能用它來轉換掉constness:
int firstNumber, secondNumber;
...
double result = dynamic_cast<double>(firstNumber)/secondNumber;
// 錯誤!沒有繼承關系
const SpecialWidget sw;
...
update(dynamic_cast<SpecialWidget*>(&sw));
// 錯誤! dynamic_cast不能轉換
// 掉const。
如你想在沒有繼承關系的類型中進行轉換,你可能想到static_cast。如果是為了去除const,你總得用const_cast。
這四個類型轉換符中的最后一個是reinterpret_cast。使用這個操作符的類型轉換,其的轉換結果幾乎都是執(zhí)行期定義(implementation-defined)。因此,使用reinterpret_casts的代碼很難移植。
reinterpret_casts的最普通的用途就是在函數(shù)指針類型之間進行轉換。例如,假設你有一個函數(shù)指針數(shù)組:
typedef void (*FuncPtr)(); // FuncPtr is 一個指向函數(shù)
// 的指針,該函數(shù)沒有參數(shù)
// 返回值類型為void
FuncPtr funcPtrArray[10]; // funcPtrArray 是一個能容納
// 10個FuncPtrs指針的數(shù)組
讓我們假設你希望(因為某些莫名其妙的原因)把一個指向下面函數(shù)的指針存入funcPtrArray數(shù)組:
int doSomething();
你不能不經(jīng)過類型轉換而直接去做,因為doSomething函數(shù)對于funcPtrArray數(shù)組來說有一個錯誤的類型。在FuncPtrArray數(shù)組里的函數(shù)返回值是void類型,而doSomething函數(shù)返回值是int類型。
funcPtrArray[0] = &doSomething; // 錯誤!類型不匹配
reinterpret_cast可以讓你迫使編譯器以你的方法去看待它們:
funcPtrArray[0] = // this compiles
reinterpret_cast<FuncPtr>(&doSomething);
轉換函數(shù)指針的代碼是不可移植的(C++不保證所有的函數(shù)指針都被用一樣的方法表示),在一些情況下這樣的轉換會產(chǎn)生不正確的結果(參見條款M31),所以你應該避免轉換函數(shù)指針類型,除非你處于著背水一戰(zhàn)和尖刀架喉的危急時刻。一把鋒利的刀。一把非常鋒利的刀。
如果你使用的編譯器缺乏對新的類型轉換方式的支持,你可以用傳統(tǒng)的類型轉換方法代替static_cast, const_cast, 以及reinterpret_cast。也可以用下面的宏替換來模擬新的類型轉換語法:
#define static_cast(TYPE,EXPR) ((TYPE)(EXPR))
#define const_cast(TYPE,EXPR) ((TYPE)(EXPR))
#define reinterpret_cast(TYPE,EXPR) ((TYPE)(EXPR))
你可以象這樣使用使用:
double result = static_cast(double, firstNumber)/secondNumber;
update(const_cast(SpecialWidget*, &sw));
funcPtrArray[0] = reinterpret_cast(FuncPtr, &doSomething);
這些模擬不會象真實的操作符一樣安全,但是當你的編譯器可以支持新的的類型轉換時,它們可以簡化你把代碼升級的過程。
沒 有一個容易的方法來模擬dynamic_cast的操作,但是很多函數(shù)庫提供了函數(shù),安全地在派生類與基類之間進行類型轉換。如果你沒有這些函數(shù)而你有必 須進行這樣的類型轉換,你也可以回到C風格的類型轉換方法上,但是這樣的話你將不能獲知類型轉換是否失敗。當然,你也可以定義一個宏來模擬 dynamic_cast的功能,就象模擬其它的類型轉換一樣:
#define dynamic_cast(TYPE,EXPR) (TYPE)(EXPR)
請記住,這個模擬并不能完全實現(xiàn)dynamic_cast的功能,它沒有辦法知道轉換是否失敗。
我 知道,是的,我知道,新的類型轉換操作符不是很美觀而且用鍵盤鍵入也很麻煩。如果你發(fā)現(xiàn)它們看上去實在令人討厭,C風格的類型轉換還可以繼續(xù)使用并且合 法。然而,正是因為新的類型轉換符缺乏美感才能使它彌補了在含義精確性和可辨認性上的缺點。并且,使用新類型轉換符的程序更容易被解析(不論是對人工還是 對于工具程序),它們允許編譯器檢測出原來不能發(fā)現(xiàn)的錯誤。這些都是放棄C風格類型轉換方法的強有力的理由。還有第三個理由:也許讓類型轉換符不美觀和鍵 入麻煩是一件好事。

posted on 2006-04-19 20:52 芥之舟 閱讀(673) 評論(0)  編輯 收藏 引用 所屬分類: C/C++

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <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>
            欧美日韩第一区| 亚洲视频在线二区| 亚洲伊人一本大道中文字幕| 亚洲国产精品久久久久秋霞蜜臀| 国产日韩欧美在线播放| 国产一区91| 影音先锋一区| 一本色道**综合亚洲精品蜜桃冫 | 久久九九免费| 欧美freesex8一10精品| 欧美色视频一区| 国产一区在线观看视频| 1024亚洲| 中文无字幕一区二区三区| 亚洲成人自拍视频| 欧美日韩一区二区国产| 国产精品黄色| 黄色一区二区在线| 99精品欧美一区二区三区综合在线 | 99精品视频免费全部在线| 亚洲综合国产| 免费观看在线综合| 国产精品美女久久福利网站| 一区视频在线看| 亚洲免费视频观看| 亚洲第一区在线观看| 一区二区日本视频| 久久久久看片| 国产乱子伦一区二区三区国色天香| 伊人狠狠色j香婷婷综合| 亚洲一二三级电影| 欧美福利电影在线观看| 欧美一区激情| 国产精品国产精品| 99国内精品久久| 美女爽到呻吟久久久久| 亚洲免费婷婷| 欧美性事在线| 一区二区精品在线| 欧美成人资源网| 欧美在线视频一区二区三区| 国产精品久久久久aaaa| 99av国产精品欲麻豆| 欧美福利一区| 久久人人超碰| 国内精品久久久久久久影视麻豆| 午夜精品久久久久久久久久久| 亚洲人成在线播放网站岛国| 蜜桃av一区| 亚洲第一久久影院| 久久亚洲私人国产精品va| 亚洲一区影音先锋| 国产精品香蕉在线观看| 亚洲欧美日韩在线不卡| 一本色道久久88精品综合| 欧美激情五月| 亚洲伦伦在线| 亚洲精品五月天| 欧美日韩日本国产亚洲在线| 一本大道久久a久久综合婷婷| 欧美激情综合色| 欧美69wwwcom| 夜夜嗨av一区二区三区四季av| 亚洲国产欧美在线人成| 欧美va天堂在线| 91久久精品一区二区三区| 欧美大片18| 欧美激情视频一区二区三区免费| 亚洲精品久久久久久久久久久| 亚洲一区二区三区免费视频| av成人国产| 国产精品国产三级国产专播精品人 | 国语自产精品视频在线看8查询8| 欧美中文字幕在线视频| 欧美一区二区日韩一区二区| 国产亚洲欧美aaaa| 老司机一区二区三区| 久热国产精品| 99精品欧美| 亚洲女女做受ⅹxx高潮| 一区二区三区在线不卡| 亚洲国产高清自拍| 国产精品大全| 噜噜噜在线观看免费视频日韩| 美日韩精品视频免费看| 一区二区三区精品在线| 亚洲尤物视频网| 亚洲高清激情| 亚洲午夜小视频| 黑人巨大精品欧美一区二区小视频 | 久久午夜精品| 欧美激情一区二区三区四区| 在线一区二区日韩| 欧美在线观看你懂的| 亚洲精品日产精品乱码不卡| 亚洲一区二区精品| 亚洲国产国产亚洲一二三| 一区二区三区高清不卡| 影音先锋在线一区| 中文亚洲欧美| 亚洲国产小视频在线观看| 中文日韩电影网站| 亚洲高清久久久| 亚洲综合电影| 亚洲天堂久久| 麻豆亚洲精品| 久久se精品一区精品二区| 欧美韩日视频| 久久躁日日躁aaaaxxxx| 欧美午夜精品久久久久免费视| 久久综合久色欧美综合狠狠| 欧美日韩综合另类| 亚洲激情欧美| 亚洲激情综合| 久久久99久久精品女同性| 欧美一区二区成人6969| 欧美日韩精品一本二本三本| 欧美大胆成人| 悠悠资源网亚洲青| 香蕉久久久久久久av网站| 宅男噜噜噜66国产日韩在线观看| 美女网站在线免费欧美精品| 久久米奇亚洲| 狠狠操狠狠色综合网| 在线视频一区观看| 欧美 亚欧 日韩视频在线| 久久九九热re6这里有精品| 国产精品成人在线观看| 99re6热在线精品视频播放速度| 亚洲国产经典视频| 久久久青草婷婷精品综合日韩 | 欧美国产第一页| 伊人久久婷婷色综合98网| 欧美在线欧美在线| 久久久国产精品一区| 国产婷婷精品| 欧美在线免费视屏| 久久中文字幕导航| 黄色在线一区| 久久婷婷麻豆| 欧美激情第8页| 亚洲肉体裸体xxxx137| 欧美激情 亚洲a∨综合| 亚洲美女91| 亚洲欧美国产日韩中文字幕| 国产精品久久久久影院色老大| 亚洲女人天堂成人av在线| 香蕉久久一区二区不卡无毒影院| 国产精品久久久久三级| 小嫩嫩精品导航| 美女诱惑黄网站一区| 亚洲人妖在线| 国产精品v欧美精品v日韩精品| 中文一区二区| 久久裸体艺术| 亚洲精品美女在线| 欧美日韩在线一区二区三区| 亚洲视频图片小说| 久久一区二区视频| 亚洲全部视频| 国产精品免费看久久久香蕉| 欧美专区在线观看| 亚洲高清不卡在线观看| 亚洲永久视频| 亚洲高清网站| 国产精品日韩一区二区| 久久精品一区蜜桃臀影院| 亚洲精品韩国| 久久婷婷综合激情| 国产精品99久久久久久宅男 | 麻豆国产va免费精品高清在线| 亚洲免费久久| 韩国一区电影| 欧美三区在线观看| 欧美在线地址| av成人免费观看| 噜噜噜噜噜久久久久久91| 一区二区三区蜜桃网| 精品不卡一区二区三区| 国产精品家教| 欧美不卡三区| 性久久久久久| 99re6这里只有精品| 欧美 日韩 国产在线| 午夜在线成人av| 9色精品在线| 亚洲大胆在线| 国产一区二区三区免费不卡| 欧美成人免费全部| av成人手机在线| 欧美成熟视频| 久久成人亚洲| 亚洲欧美激情四射在线日| 亚洲国产三级在线| 狠狠狠色丁香婷婷综合久久五月| 欧美日韩情趣电影| 欧美激情在线免费观看| 浪潮色综合久久天堂| 久久久91精品| 久久国产高清|