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

洛譯小筑

別來無恙,我的老友…
隨筆 - 45, 文章 - 0, 評論 - 172, 引用 - 0
數據加載中……

[ECPP讀書筆記 條目22] 將數據成員聲明為私有的

好吧,以下是我們的計劃:我們首先要分析為什么數據成員不應該是公有的,然后繼續分析為什么數據成員也不能是protected的。然后就引出本條款的結論:數據成員必須是私有的。結論引出,計劃完成。

那么,數據成員為什么不能是public的?

讓我們從討論語義一致性問題開始(另請參見條目18)。如果數據成員不是公有的,那么客戶要想訪問對象就只剩下成員函數一種方法。如果公有接口中所有的東西都是函數,那么客戶在期望訪問類成員時,由于一切都是函數,所以就可以任意使用,而不用擔心是否需要使用括號。在整個過程中,這樣做可以讓你節省大量躊躇不定的時間。

但是也許你會發現,并沒有強制規定來要求語義的一致性。那么你是否會發現:使用函數可以讓你更精確地控制數據成員的訪問權?如果把一個數據成員定義為public的,那么每個人對其都擁有“可讀可寫”的訪問權,但是如果你使用函數來為數據成員賦值,或者獲取數據成員的值,那么你可以將其實現為“禁止訪問”、“只讀”以及“可讀可寫”幾種級別的訪問權;嘿,如果需要,你甚至可以將其實現為“只寫”的訪問權:

class AccessLevels {

public:

  ...

  int getReadOnly() const    { return readOnly; }

  void setReadWrite(int value) { readWrite = value; }

  int getReadWrite() const   { return readWrite; }

  void setWriteOnly(int value) { writeOnly = value; }

 

private:

  int noAccess;               // int值禁止訪問

  int readOnly;               // int值擁有只讀級別訪問權

  int readWrite;              // int值擁有可讀可寫級別訪問權

  int writeOnly;              // int值擁有只寫級別訪問權

};

很有必要將訪問權管理得如此有條不紊,因為許多數據成員本應該被隱藏起來。并不是每個數據成員都需要一個取值器(getter)和一個賦值器(setter)。

還不是十分肯定?那么現在是時候使出殺手锏了:“封裝”。如果你通過程序實現了對一個數據成員的訪問,那么你就可以使用一次計算來代替這個數據成員,使用這一個類的人完全不會有所察覺。

請看下邊的示例,假設你正在為一種自動裝置編寫一個應用程序,這一裝置可以監視通過汽車的行駛速度,當一輛汽車通過時,這一應用程序就會計算出它的速度,然后將這一數值保存到一個小型數據庫中,其中保存著曾通過所有車輛的速度數據:

class SpeedDataCollection {

  ...

public:

  void addValue(int speed);        // 添加新的數據值

 

  double averageSoFar() const;     // 返回速度的平均值

 

  ...

};

現在請注意成員函數averageSoFar的具體實現問題。一種實現方法是:為類添加一個數據成員,讓它保存速度的平均值,隨數據庫的改動更新這一成員的數值。當調用averageSoFar時,它僅僅返回這一數據成員的值。另一種做法是:在每次調用averageSoFar時都計算出這一平均值,此時需要檢查數據庫中所有的數據值。

因為第一種手段(保存即時更新的平均值)中,你需要為保存即時更新平均值、累計總和以及數據的個數這幾種數據成員分配空間,因此這一方法使得SpeedDataCollection對象都變得更大一些。然而,averageSoFar卻十分的高效。可以把它寫成一個內聯函數(參見條目30),所做的僅僅是返回這一即時更新的。相反地,在需要時進行計算,averageSoFar速度上會慢一些,但是SpeedDataCollection對象的體積更小。

二者孰優孰劣,誰又能斷定呢?在一個內存較為局促的機器(比如嵌入式的公路設備)上,并且該應用程序不會頻繁的調用平均值,那么實時計算的方案就更為優秀。相反地,在平均值需要頻繁使用,速度是程序的關鍵,內存不是問題的情況下,則更應采用保存一個即時平均值的方案。最重要的一點是,在通過成員函數訪問平均值時(也就是“封裝”),你可以交替使用這兩種實現方案(當然,你可能還會想到其它重要的問題),客戶頂多要做的一件事就是重新編譯一下代碼。(即使編譯所帶來的不方便也可以排除。參見條目31中介紹的技術。)

將數據成員隱藏在函數式接口的背后可以使得任意種類的實現方法更加靈活多變。比如說,這樣做可以非常容易地做到下面幾件事情:在數據成員進行讀寫操作時告知其他對象,驗證類的恒定性和函數運行前后的狀態,在多線程系統下進行同步操作,等等。如果讓DelphiC#的程序員使用C++,他們會發現C++這一特性與這些語言中的“屬性”很相像,只是C++中需要添加一對括號。

封裝是C++的一個博大精深的特性。如果你對客戶隱藏了數據成員的話(也就是將它們封裝起來),你就可以確保類永遠保持一致性,這是因為只有成員函數可以影響到數據成員,同時你也保留了在以后改變具體實現方法的權利。如果你不將這些方法隱藏起來,那么你很快就會發現,即使你擁有類的源代碼,對公有接口的修改也是受到嚴格限制的,因為這樣做會破壞許多客戶端代碼。公有就意味著未封裝,同時從實用角度講,未封裝就意味著無法更改,較為廣泛應用的類更甚之。然而廣泛應用的類最需要使用封裝,因為它們可以從“具體實現可以不斷改良”這一點上獲得最大程度的收益。

上面的分析對于protected數據成員也適用。盡管二者乍看上去有一定的區別,但實際上它們是完全一致的。在使用public數據成員時,我們分析了語意一致性問題和訪問權條理性問題,這一分析過程對于使用protected數據同樣適用。但還有一個問題——封裝。protected數據成員不是比public的更具有封裝性嗎?從實用角度講,你會得到一個令人吃驚的答案:不是。

條目23中將介紹這一問題:C++中封裝程度與代碼的健壯程度(這段代碼相關部分被修改時抵御破壞的能力)成正比。因此,數據成員的封裝程度與代碼的健壯程度也是成正比的。比如,當一個數據成員從類中移除時(可能你期望使用一次計算來代替,就像上文中的averageSoFar一樣),代碼是否會遭到破壞,將取決于封裝程度。

請考慮這個問題:假設我們有一個public數據成員,然后我們把它刪除了,那么將有多少的代碼將遭到破壞呢?我們說,所有使用它的客戶端代碼。這將是一個無法預知的巨大數字。公有數據成員就是這樣完全沒有封裝性的。但是繼續考慮:我們有一個protected數據成員,然后我們把它刪除了,此時將破壞多少代碼?我們說,所有使用它的派生類,這同樣是一個無法預知的巨大數字。由于在這兩種情況下,如果數據成員被更改了,那么將會為客戶帶來無法估量的損失,因此可以說protected數據成員與public的一樣沒有封裝性。這是違背直覺的,但是有經驗的庫實現者會告訴你,這是千真萬確的。一旦你聲明了一個publicprotected的數據成員,然后客戶開始使用它,你就很難再對這一數據成員做出修改。因為這樣做會帶來太多的代碼重寫、重新測試重新編寫文檔和重新編譯等等工作。按封裝的理念來說,對于數據成員僅僅存在兩個層次的訪問權,那就是:private(可以提供封裝性)和非private(不提供封裝性)。

時刻牢記

要將數據成員聲明為私有的。這樣可以讓客戶端訪問數據時擁有一致的語義,提供有序的訪問控制,強制類保持一致性,為類作者提供更高的靈活性。

protected并不會帶來比public更高的封裝性。

posted on 2007-06-06 18:37 ★ROY★ 閱讀(1037) 評論(0)  編輯 收藏 引用 所屬分類: Effective 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>
            夜夜嗨av一区二区三区网站四季av| 欧美一区二区播放| 狼人社综合社区| 久久av一区| 亚洲国产1区| 亚洲激情av| 欧美激情影音先锋| 一区二区三区导航| 亚洲作爱视频| 国产一级一区二区| 亚洲色图在线视频| 久热re这里精品视频在线6| 红桃视频欧美| 最新中文字幕一区二区三区| 欧美日韩一二三区| 欧美一级大片在线免费观看| 欧美在线视屏| 一区二区三区日韩在线观看| 亚洲自拍三区| 亚洲国产精品一区制服丝袜| 亚洲欧洲日韩综合二区| 国产精品一区二区久激情瑜伽| 久久久91精品| 欧美另类极品videosbest最新版本| 亚洲图片你懂的| 久久久www成人免费毛片麻豆| 亚洲精品一区二区三| 亚洲一区二区欧美| 亚洲精品国偷自产在线99热| 亚洲视频你懂的| 亚洲人成久久| 欧美有码在线视频| 99精品视频免费| 久久精品国产一区二区电影| 在线亚洲欧美专区二区| 久久一日本道色综合久久| 亚洲小视频在线观看| 久久免费黄色| 久久aⅴ国产紧身牛仔裤| 欧美激情一区二区在线| 久久嫩草精品久久久精品| 欧美日韩中文另类| 亚洲第一天堂无码专区| 国产欧美在线播放| 一本色道久久加勒比88综合| 亚洲高清不卡av| 久久久7777| 久久不见久久见免费视频1| 欧美日韩亚洲天堂| 亚洲国产另类久久久精品极度| 国产专区综合网| 亚洲免费在线电影| 亚洲午夜在线观看| 欧美裸体一区二区三区| 欧美成人久久| 在线不卡亚洲| 久久精品一区二区三区四区| 欧美一区二区成人6969| 欧美视频导航| 99精品久久| 在线一区二区三区做爰视频网站 | 亚洲成色www久久网站| 国产亚洲欧洲| 欧美伊人久久久久久久久影院| 午夜精品亚洲一区二区三区嫩草| 欧美久久99| 99天天综合性| 性欧美videos另类喷潮| 国产精品区一区二区三| 中文一区二区| 亚洲欧美久久久| 国产精一区二区三区| 亚洲男人的天堂在线| 在线亚洲自拍| 亚洲免费一级电影| 国产精品国产三级国产| 一区二区欧美国产| 欧美在线国产精品| 国产欧美一区二区精品性| 午夜一区二区三视频在线观看| 久久国产精彩视频| 在线观看亚洲精品| 欧美激情精品久久久久久蜜臀| 最新成人av网站| 午夜精品久久久久久久久久久久 | 久久只精品国产| 亚洲精品一区二区三区福利| 亚洲视频在线观看视频| 国产精品一二三四| 毛片av中文字幕一区二区| 亚洲国产日韩欧美在线动漫| 在线视频中文亚洲| 国产亚洲精品久| 麻豆freexxxx性91精品| 99综合在线| 久久久久在线| 宅男噜噜噜66国产日韩在线观看| 国产日本亚洲高清| 欧美激情综合五月色丁香| 亚洲一区不卡| 欧美大胆人体视频| 篠田优中文在线播放第一区| 在线成人激情黄色| 国产精品日韩精品| 另类av导航| 亚洲欧美日韩系列| 亚洲第一区色| 久久av一区| 亚洲午夜激情在线| 在线成人国产| 国产日韩精品一区| 欧美母乳在线| 久久综合狠狠综合久久综合88| 妖精成人www高清在线观看| 另类天堂视频在线观看| 亚洲中午字幕| 一个色综合av| 亚洲人成在线观看| 伊人男人综合视频网| 国产精品人成在线观看免费| 欧美福利在线| 久久综合久久综合久久| 香蕉成人啪国产精品视频综合网| 亚洲精品在线电影| 欧美成人激情视频| 久久精品国产第一区二区三区最新章节 | 久久久噜噜噜久久狠狠50岁| 999在线观看精品免费不卡网站| 久久一区亚洲| 久久久精品国产免费观看同学| 亚洲午夜精品网| aa日韩免费精品视频一| 亚洲日本aⅴ片在线观看香蕉| 国产亚洲一级| 国产一本一道久久香蕉| 国产精品网站在线观看| 国产精品久久久久久久久免费桃花| 欧美精品一区二区蜜臀亚洲| 免费在线日韩av| 久久亚洲二区| 久久综合色影院| 久久免费少妇高潮久久精品99| 亚洲综合色噜噜狠狠| 在线亚洲精品| 亚洲精品乱码久久久久久久久| 欧美激情视频网站| 欧美成人情趣视频| 欧美激情国产日韩| 亚洲福利视频网| 亚洲国产日韩欧美综合久久 | 亚洲一卡久久| 亚洲午夜激情网站| 午夜久久久久| 久久国产乱子精品免费女 | 欧美在线观看日本一区| 欧美一站二站| 久热国产精品视频| 欧美高清在线精品一区| 亚洲人成在线免费观看| 一区二区三区四区国产精品| 亚洲视频在线观看免费| 午夜免费日韩视频| 久久偷看各类wc女厕嘘嘘偷窃| 蜜臀a∨国产成人精品| 欧美高清在线观看| 国产精品久久久久久久一区探花| 国产精品女人久久久久久| 国产亚洲精品久久飘花| 亚洲青涩在线| 午夜在线精品偷拍| 免费看成人av| 一本色道久久综合精品竹菊| 亚洲在线观看免费| 久久久久久9999| 欧美日韩免费观看一区三区| 国产欧美激情| 亚洲精品日韩久久| 香蕉国产精品偷在线观看不卡| 久久综合给合| 日韩亚洲不卡在线| 久久久久久**毛片大全| 欧美日韩中文字幕精品| 国内一区二区三区在线视频| 日韩亚洲欧美精品| 久久五月天婷婷| 一本色道久久综合亚洲精品婷婷| 久久精品系列| 国产精品视频精品视频| 亚洲国产精品一区二区尤物区| 亚洲欧美日韩直播| 亚洲国产高潮在线观看| 欧美一区二区免费观在线| 欧美激情一区在线| 狠狠综合久久av一区二区小说| 亚洲图片自拍偷拍| 欧美激情亚洲自拍| 午夜久久福利| 国产精品狠色婷| 在线一区亚洲| 亚洲电影观看|