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

歸去來兮

 

Effective C++讀書筆記之二 :盡可能使用const

條款三:盡可能使用const(use const whenever possible)
const允許你指定一個語義約束,而編譯器會強制實施這項約束。它允許你告訴編譯器和其他程序員某值應(yīng)該保持不變。有一條約束需要注意,那就是:如果const出現(xiàn)在*號的左邊,那就是說被指物是常量;如果出現(xiàn)在星號右邊,則表示指針本身是常量;如果出現(xiàn)在兩邊,則被指物和指針都是常量。如果被指物是常量,則關(guān)鍵字const寫在類型的前面和類型之后,星號之前兩種所表示的語義是相同的。例如下面這兩種寫法是一樣的:
void f1(const Widget* pw);
void f2(Widget const * pw);
const也可用來修飾STL中的迭代器。聲明迭代器為const就想聲明指針為const一樣(即T* const 指針),表示這個迭代器不得指向不同的東西。但它所指的東西的值是可以改變的。如果希望迭代器所指的東西不可改變(即模擬一個const T*指針),需要的是const_iterator:
std::vector<int> vec;
...
const std::vector<int>::iterator iter = vec.begin();// same as T* const
*iter = 10;                                                        //no problem
++iter;                                                              //wrong!!
std::vector<int>::const_iterator cIter = vec.begin();//same as const T*
*iter = 10;                                                             //wrong!!
++iter;                                                                  //no problem

const 最具威力(?)的用法是面對函數(shù)聲明時的應(yīng)用。在一個函數(shù)聲明式內(nèi),const可以和函數(shù)返回值,各參數(shù),函數(shù)自身(成員函數(shù))產(chǎn)生關(guān)聯(lián)。
令函數(shù)返回一個常量值,往往可以降低因客戶錯誤而造成的意外,而又不至于放棄安全性和高效性。例如,考慮有理數(shù)的operator*聲明式:
class Rational(){...};
const Rational operator* (const Rational & lhs, const Rational & rhs);
也許你會說為什么返回一個const對象?原因是如果不這樣別人可能實現(xiàn)這樣的暴行:
Rational a,b,c;
...
(a*b)=c;
下面,主要說明const作用于成員函數(shù)。
許多人都忽視了這么一個事實,那就是如果兩個成員函數(shù)只是常量性不同,那么他們是可以重載的。考慮以下這個用來表示一大塊文字的class:

class TextBlock{
public:

const char& operator[](std::size_t position) const
{return text[position];}
char& operator[](std::size_t position)
{return text[position];}
private:
std::
string text;
}
;
TextBlock的operator[]可以這么使用:
TextBlock tb(
"Hello");
std::cout 
<< tb[0];  //調(diào)用non-const 

const TextBlock ctb("Hello");
std::cont 
<< ctb[0]; //調(diào)用const

真是情形中const對象多用于passed by pointer-to-const或passed by reference-to-const的傳遞結(jié)果。上述的ctb太過于造作,下邊這個比較真實:
void print (const TextBlocd& ctb)
{
  std::cout 
<< ctb[0];
  
}

只用重載operator[]并對不同的版本給予不同的返回類型,就可以令const和non-const獲得不同的處理。
此處需要注意一點,non-const operator[]的返回類型是個reference to char,不是char。如果operator[]返回的是個char,下邊的賦值就不能通過編譯:
tb[0] = 'x'; //error c2106: ' = ' : left operand must be l-value
那是因為,如果函數(shù)的返回類型是個內(nèi)置類型,那么改動函數(shù)的返回值從來就不合法。縱使合法,C++以by value返回對象這一事實(條款20)意味著改動的其實只是tb.text[0]的一個副本,不是tb.text[0]本身,那不是我們想要的結(jié)果。
下邊來說說在const和non-const成員函數(shù)中避免重復(fù)
假設(shè)TextBlock(和CTextBlock)內(nèi)的operator[]不單只是返回一個reference指向某字符,也執(zhí)行邊界檢查、志記訪問信息、甚至可能進行數(shù)據(jù)完整性檢驗。把所有這些同時放進const和non-const operator[]中,導(dǎo)致這樣的一個怪物:
class TextBlock{
public:

const char& operator[](std::size_t position) const
{
      
//邊界檢查(bounds checking)
      //志記數(shù)據(jù)訪問(log access data)
      //檢驗數(shù)據(jù)完整性(verify data integrity)
return text[position];
}

char& operator[](std::size_t position)
{
      
//邊界檢查(bounds checking)
      //志記數(shù)據(jù)訪問(log access data)
      //檢驗數(shù)據(jù)完整性(verify data integrity)
return text[position];
}

private:
std::
string text;
}
;
其中代碼的代碼重復(fù)性及伴隨的編譯時間,維護,代碼膨脹等問題真是令人頭疼啊。當然了,將邊界檢查……等所有代碼移植到另一個成員函數(shù),并令兩個版本的operator[]調(diào)用它,是可能的,但是還是重復(fù)了一些代碼,例如函數(shù)調(diào)用,兩次return語句等。
我們真正要做的,是實現(xiàn)operator[]的機能一次并使用它兩次。也就是說,你必須使一個調(diào)用另一個。這促使我們將常量性轉(zhuǎn)除(casting away constness)。
就一般而言,casting是一個糟糕的想法,在條款27中有詳細的說明。然而代碼重復(fù)也不是什么令人愉快的經(jīng)驗。本例中cosnt operator[]完全做掉了non-const版本該做的一切,唯一不同是其返回類型多了一個const資格修飾。這種情況下如果將返回值的const轉(zhuǎn)除是安全的,因為不論誰調(diào)用non-const operator[]都一定首先有個non-const對象,否則就不能夠調(diào)用non-const函數(shù)。所以令non-const operator[]調(diào)用其const兄弟是一個避免重復(fù)的安全做法:
class TextBlock{
public:

const char& operator[](std::size_t position) const
{



return text[position];
}

char& operator[](std::size_t position)
{
const_cast
<char&>(static_cast<const TextBlock&>
(
*this)[position]);
}


}
;
這里面有兩個轉(zhuǎn)型動作,而不是一個。我們打算讓non-const operator[]調(diào)用const兄弟,但是non-const如果只是單純調(diào)用operator[],會遞歸調(diào)用自己。為了避免無窮遞歸,我們必須明確指出調(diào)用的是const operator[]。因此,這里將*this從其原始類型TextBlock&轉(zhuǎn)型為const TextBlock&。所以這里有兩次轉(zhuǎn)型:第一次用來為*this添加const,第二次則是從const operator[]的返回值中移除const。添加const的那一次轉(zhuǎn)型強迫進行了一次安全轉(zhuǎn)型,所以采用static_cast。移除const的那個動作只能由const_cast完成,沒有其他選擇。
下面來考慮一下反向的做法:令const來調(diào)用non-const以避免重復(fù)。這個不是我們應(yīng)該做的。const成員函數(shù)承諾絕對不改變其對象的邏輯狀態(tài),non-const成員函數(shù)卻沒有這般承諾。如果在const函數(shù)內(nèi)部調(diào)用了non-const函數(shù),就是冒了這樣的風(fēng)險:你曾經(jīng)承諾不改動的那個對象被改動了。這就是為什么“const成員函數(shù)調(diào)用non-const成員函數(shù)”是一種錯誤行為:因為對象有可能因此而被改動。反向調(diào)用才是安全的:non-const函數(shù)本來就可以對其對象做任何動作,所以在其中調(diào)用一個const成員函數(shù)并不會帶來任何風(fēng)險。

本條目總結(jié):

Things to Remember

  • Declaring something const helps compilers detect usage errors. const can be applied to objects at any scope, to function parameters and return types, and to member functions as a whole.

  • Compilers enforce bitwise constness, but you should program using conceptual constness.

  • When const and non-const member functions have essentially identical implementations, code duplication can be avoided by having the non-const version call the const version.

posted on 2008-12-09 23:00 Edmund 閱讀(292) 評論(0)  編輯 收藏 引用


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


導(dǎo)航

統(tǒng)計

常用鏈接

留言簿(1)

隨筆分類

隨筆檔案

搜索

最新評論

閱讀排行榜

評論排行榜

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <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>
            欧美大片专区| 日韩午夜电影av| 久久精品国产久精国产思思| 国产嫩草一区二区三区在线观看 | 免费欧美在线视频| 狠狠色伊人亚洲综合网站色| 老司机凹凸av亚洲导航| 蜜臀av国产精品久久久久| 亚洲精选视频在线| 制服丝袜亚洲播放| 国产日韩欧美综合| 欧美成人精品福利| 欧美日韩精品免费观看视一区二区 | 亚洲肉体裸体xxxx137| 亚洲精品久久久久久久久久久久久 | 久久亚洲精品伦理| 亚洲精品一二三区| 亚洲午夜视频在线观看| 国产一区二区无遮挡| 亚洲国产精品黑人久久久| 欧美日韩激情网| 久久爱91午夜羞羞| 欧美电影免费观看| 欧美淫片网站| 欧美精品 日韩| 久久都是精品| 欧美精品三级| 久久久在线视频| 欧美视频精品在线| 欧美国产欧美亚洲国产日韩mv天天看完整 | 亚洲无线一线二线三线区别av| 亚洲影音一区| 日韩午夜免费| 久久激情综合网| 亚洲天天影视| 欧美成人精品影院| 久久精品99久久香蕉国产色戒| 老司机一区二区| 亚洲欧美综合国产精品一区| 欧美不卡视频| 美女精品一区| 国产日本欧美视频| 亚洲天堂免费观看| 99精品国产高清一区二区 | 一区二区欧美激情| 亚洲国产日韩欧美| 久久精品视频在线免费观看| 亚洲一区中文| 欧美日韩国产一区| 亚洲成色www久久网站| 亚洲日韩中文字幕在线播放| 国产午夜精品一区二区三区欧美| 99热精品在线观看| 亚洲狼人综合| 欧美激情综合五月色丁香小说| 久久在线精品| 黄色一区二区在线观看| 午夜伦欧美伦电影理论片| 亚洲小说区图片区| 欧美日韩国产成人高清视频| 欧美成人精品一区二区三区| 国产午夜精品视频| 欧美一区二区视频在线| 久久爱www| 国产日韩欧美综合| 性做久久久久久| 久久国产精品久久久| 国产日韩视频| 欧美一区1区三区3区公司| 欧美一区日韩一区| 国产日韩欧美在线一区| 午夜日韩福利| 久久中文字幕导航| 亚洲第一区在线| 巨乳诱惑日韩免费av| 久久亚洲私人国产精品va| 激情丁香综合| 欧美成人免费va影院高清| 亚洲国产一区二区三区青草影视| 亚洲国产片色| 欧美人体xx| 正在播放亚洲一区| 久久精品视频免费播放| 在线观看亚洲专区| 欧美激情久久久久| 这里只有精品丝袜| 久久久久九九九九| 亚洲激情视频网站| 国产精品h在线观看| 香蕉久久夜色精品国产| 女主播福利一区| 中文高清一区| 国产亚洲一区在线| 欧美精品久久久久久久| 在线视频亚洲欧美| 久久一综合视频| 夜夜嗨av一区二区三区网站四季av| 欧美三日本三级三级在线播放| 亚洲一区二区三区免费视频| 久久影院亚洲| 亚洲无限av看| 尤物九九久久国产精品的特点| 欧美国产日韩视频| 午夜精品久久久久久久99热浪潮| 欧美mv日韩mv国产网站app| a91a精品视频在线观看| 国产日韩欧美中文| 欧美日韩成人综合在线一区二区| 亚洲一区三区视频在线观看| 欧美电影电视剧在线观看| 亚洲色图在线视频| 欲色影视综合吧| 国产精品视频免费一区| 美女视频网站黄色亚洲| 亚洲欧美久久久| 亚洲人成7777| 欧美插天视频在线播放| 亚洲天堂网站在线观看视频| 黄色亚洲在线| 国产精品亚洲成人| 欧美日韩精品中文字幕| 另类专区欧美制服同性| 亚洲欧美视频| 亚洲视屏一区| 99精品视频免费| 亚洲国产精品免费| 欧美11—12娇小xxxx| 久久久久九九视频| 午夜视频在线观看一区| 亚洲天堂偷拍| 一区二区三区国产精华| 亚洲欧洲视频| 亚洲国产精品视频一区| 伊人久久av导航| 国内久久婷婷综合| 国产日本欧洲亚洲| 国产麻豆视频精品| 国产美女一区| 国产欧美精品va在线观看| 国产精品av免费在线观看| 欧美日本网站| 欧美日韩国产综合在线| 欧美日韩国产系列| 欧美日韩中字| 国产精品久久久久久久久免费桃花 | 亚洲国产精品一区二区第四页av| 麻豆国产精品一区二区三区| 久久夜色精品亚洲噜噜国产mv| 久久久久天天天天| 巨乳诱惑日韩免费av| 老司机凹凸av亚洲导航| 麻豆av一区二区三区久久| 免费观看国产成人| 欧美成人日韩| 亚洲精品日韩精品| 妖精视频成人观看www| 亚洲视频在线观看| 亚洲欧美偷拍卡通变态| 香蕉久久一区二区不卡无毒影院| 欧美亚洲综合久久| 久久久国产精品一区二区三区| 久久综合色8888| 欧美日韩国产区| 国产精品资源| 1024国产精品| 一区二区三区av| 欧美在线二区| 欧美成人精品1314www| 亚洲精品免费在线播放| 亚洲性夜色噜噜噜7777| 久久激情中文| 欧美激情在线播放| 国产精品亚洲综合天堂夜夜| 伊人精品在线| 亚洲一区二区三区色| 久久国产日韩| 亚洲黑丝在线| 亚洲欧美日韩在线综合| 老司机免费视频一区二区| 欧美日韩小视频| 激情伊人五月天久久综合| 亚洲精品视频在线| 欧美在线短视频| 亚洲国产精品一区二区www| 亚洲一区二区在线视频 | 亚洲美洲欧洲综合国产一区| 性一交一乱一区二区洋洋av| 欧美大片免费看| 国产偷国产偷亚洲高清97cao| 亚洲精品中文字幕女同| 久久国产一区| 亚洲精品国产视频| 久久美女性网| 国产精品久久久久毛片大屁完整版| 精品av久久久久电影| 亚洲影视综合| 亚洲国产欧美精品| 久久久精品国产免大香伊| 欧美系列亚洲系列| 亚洲欧洲日夜超级视频|