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

洛譯小筑

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

[ECPP讀書筆記 條目6] 要顯式禁止編譯器為你生成不必要的函數

真實的房地產代理商的工作是出售房屋,而一個為房產代理商提供支持的軟件系統自然要用一個類來代表要出售的房屋:

class HomeForSale { ... };

所有房地產代理商能夠很輕松的指出,每套房產都是獨一無二的——沒有兩套是完全一樣的。既然如此,為一個HomeForSale對象復制出一個副本的想法就顯得沒什么意義了。你怎么能夠復制那些生來就獨一無二的東西呢?如果你嘗試去復制一個HomeForSale對象,那么編譯器則不應該接受:

HomeForSale h1;

HomeForSale h2;

 

HomeForSale h3(h1);                // 嘗試復制h1:不應通過編譯!

h1 = h2;                           // 嘗試復制h2:不應通過編譯!

可惜的是,防止這種復雜問題發生的方法并不是那么直截了當。通常情況下,如果你希望一個類不支持某種特定的功能,你需要做的僅僅是不去聲明那個函數。然而這一策略對復制構造函數和拷貝賦值運算符就失效了,這是因為,即使你不做聲明,而一旦有人嘗試調用這些函數,編譯器就會為你自動聲明它們(參見條目5)。

這會使你便陷入困境。如果你不聲明一個復制構造函數或者賦值運算符,編譯器可能就會幫你去做,你的類就會支持對象復制。從另一個角度說,如果你確實聲明了這些函數,你的類仍然支持復制。但是現在的目標是防止復制!

解決問題的關鍵是,所有編譯器生成的函數都是公共的。為了防止編譯器生成這些函數,你必須自己聲明,但是現在沒有什么要求你將這些函數聲明為公共的。取而代之,你應該將復制構造函數和賦值運算符聲明為私有的。通過顯式聲明一個函數,你就可以防止編譯器去自動生成這個函數,同時,通過將函數聲明為private的,你便可以防止人們去調用它。

差不多了。但是這一方案也沒有那么傻瓜化,這是因為成員函數和友元函數仍然可以調用你的私有函數。除非你足夠的聰明,沒有去定義這些成員或友元。如果一些人由于疏忽大意而調用了其中的任意一個,他們會在程序連接時遇到一個錯誤。把成員函數聲明為private的但是不去實現它們,這一竅門已經成為編程常規,在C++的I/O流的庫中的一些類,都會采用這種方法來防止復制。比如,你可以參考標準庫中ios_basebasic_iossentry的實現。你會發現在各種情況下,復制構造函數和拷貝賦值運算符都聲明為private而且沒有得到定義。

HomeForSale使用這一技巧十分簡單:

class HomeForSale {

public:

  ...

private:

  ...

  HomeForSale(const HomeForSale&); // 只有聲明

  HomeForSale& operator=(const HomeForSale&);

};

你會發現我省略了函數參數的名稱。這樣做并不是必需的,這僅僅是一個普通慣例。畢竟這些代碼不會得到實現,而且很少會用到,那么給這些參數命名又有什么用呢?

通過上文中類的聲明,編譯器會防止客戶嘗試復制HomeForSale對象,如果你不小心在成員函數或者友元函數中這樣做了,那么你的程序將無法得到連接。

如果你將復制構造函數和拷貝賦值運算符聲明為private的,并且將二者移出HomeForSale的內部,放置在一個專門設計用來防止復制的基類中,那么在編譯時就排除這些原本是連接時的錯誤便成為可能(這是件好事——早期發現錯誤要比晚些更理想)。這一基類極其簡單:

class Uncopyable {

protected:                         // 允許派生類存在構造函數和析構函數

  Uncopyable() {}

  ~Uncopyable() {}

 

private:

  Uncopyable(const Uncopyable&);   // 但禁止復制

  Uncopyable& operator=(const Uncopyable&);

};

為了防止HomeForSale對象被復制,我們所需要做的僅僅是讓其繼承Uncopyable

class HomeForSale: private Uncopyable {

  ...                              // 這一類不再聲明復制構造函數和賦值運算符

};

這樣做是可行的,這是因為如果有人(甚至是一個成員或友元函數)嘗試復制一個HomeForSale對象,編譯器將會嘗試自動生成一個復制構造函數和一個拷貝賦值運算符。就像條目12中所解釋的,這些函數由編譯器自動生成的版本會嘗試調用它們基類中的這一部分,顯然這些調用只能吃到閉門羹,這是因為復制操作在基類中是私有的。

Uncopyable的實現和應用存在一些微妙的問題,諸如繼承自Uncopyable的類不一定必須為public的(參見條目32和條目39),Uncopyable的析構函數不一定必須為虛函數(參見條目7)。由于Uncopyable不包含任何數據,它適合作為空基類優化方案(參見條目39),但是由于它是一個基類,使用這一技術將導致多重繼承(參見條目40)。然而,多重繼承在某種情況下會使空基類優化失去作用(同樣,請參見條目39)。總體來說,你可以忽略這些微妙的問題,僅僅使用上文中的Uncopyable,因為它會像所承諾的那樣精確地完成工作。你也可以使用Boost版本(條目55)。那個類叫做noncopyable。它是一個優秀的類,我只是發現它的名字顯得有些不自然(un-natural),呃,“非”自然(non-natural)。

時刻牢記

為了禁用編譯器自動提供的功能,你必須將相關的成員函數聲明為private的,同時不要實現它。方法之一是:使用一個類似于Uncopyable的基類。

posted on 2007-04-18 23:21 ★ROY★ 閱讀(1069) 評論(1)  編輯 收藏 引用 所屬分類: Effective C++

評論

# re: 【翻譯】Effective C++ (第6條:要顯式禁止編譯器為你生成不必要的函數)  回復  更多評論   

// 這一類不再聲明復制構造器和賦值運算符。

這句話蠻重要,呵呵
2007-05-22 15:05 | recorder
青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <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性教育| 国产欧美日韩一区二区三区在线| 国产日产精品一区二区三区四区的观看方式 | 亚洲在线免费视频| 香蕉国产精品偷在线观看不卡| 欧美一区二区三区电影在线观看| 久久久久久午夜| 亚洲黄色免费| 在线视频亚洲| 久久久青草青青国产亚洲免观| 欧美国产先锋| 国产欧美在线看| 亚洲精品一区二区三区婷婷月 | 国产精品地址| 一区二区三区在线免费视频| 亚洲靠逼com| 欧美在线观看视频在线| 欧美风情在线| 亚洲欧美伊人| 久久免费高清视频| 99在线热播精品免费| 欧美在线视频在线播放完整版免费观看 | 久久久噜噜噜久久中文字免| 亚洲国产另类精品专区| 午夜精彩国产免费不卡不顿大片| 久久综合色综合88| 国产麻豆一精品一av一免费| 亚洲精品一区二区三区婷婷月 | 久久久噜噜噜久久中文字幕色伊伊| 亚洲高清电影| 欧美影院在线| 国产精品视频一区二区三区| 一本不卡影院| 亚洲第一精品电影| 久久久久久久久久久久久女国产乱 | 亚洲国产精品va在线看黑人| 亚洲欧美一区二区激情| 国产精品国产三级国产专播精品人 | 亚洲视频专区在线| 欧美经典一区二区三区| 1000部国产精品成人观看| 欧美一区二视频| 一区二区三区日韩在线观看| 欧美日韩成人激情| 亚洲欧洲三级电影| 欧美激情一区| 欧美电影专区| 日韩视频在线观看一区二区| 亚洲高清视频一区| 欧美国产日韩免费| 亚洲免费电影在线观看| 亚洲成在人线av| 免费久久精品视频| 亚洲激精日韩激精欧美精品| 男人的天堂亚洲| 免费在线欧美黄色| 亚洲人成在线播放网站岛国| 亚洲国产精品成人久久综合一区| 猛男gaygay欧美视频| 亚洲人精品午夜在线观看| 亚洲黄色在线| 欧美日韩午夜剧场| 午夜国产精品视频免费体验区| 亚洲淫性视频| 国内精品久久久久影院薰衣草 | 一区二区三区av| 亚洲欧洲一级| 国产精品草草| 久久久91精品| 免费在线看成人av| 亚洲新中文字幕| 欧美一区日韩一区| 亚洲成人原创| 99热在线精品观看| 国产在线播精品第三| 欧美成年人网| 国产精品高精视频免费| 久久久久久国产精品一区| 久久综合伊人77777麻豆| 亚洲精品综合精品自拍| 宅男噜噜噜66一区二区66| 国产亚洲精品一区二555| 欧美激情免费观看| 欧美视频一二三区| 久久天天躁狠狠躁夜夜av| 欧美高潮视频| 久久久久成人精品免费播放动漫| 欧美国产一区在线| 久久久精品久久久久| 欧美日本韩国一区二区三区| 久久久精品欧美丰满| 欧美日韩免费在线| 免费在线观看成人av| 国产精品久久久久久五月尺| 欧美大胆成人| 国产午夜亚洲精品理论片色戒 | 久久裸体艺术| 亚洲午夜av在线| 久久亚洲欧美国产精品乐播| 亚洲在线观看免费| 欧美成人精品激情在线观看| 欧美影院成年免费版| 欧美另类99xxxxx| 蜜臀av性久久久久蜜臀aⅴ| 国产精品人成在线观看免费| 亚洲国产日韩一级| 在线播放日韩专区| 午夜精品久久久久久久白皮肤 | 亚洲第一在线视频| 国产午夜精品全部视频播放| 亚洲免费观看视频| 亚洲区在线播放| 久久久久久久激情视频| 欧美一级理论片| 欧美视频第二页| 亚洲精品久久嫩草网站秘色| 亚洲国产高清视频| 久久久美女艺术照精彩视频福利播放| 午夜精品久久久久久久男人的天堂| 欧美成人午夜剧场免费观看| 美女日韩在线中文字幕| 国产综合久久久久久| 亚洲欧美在线网| 欧美一区二区三区四区在线观看地址| 欧美视频日韩| 亚洲视频自拍偷拍| 国产曰批免费观看久久久| 夜夜嗨av一区二区三区四区| 91久久久在线| 欧美国产视频在线| 91久久久亚洲精品| aa级大片欧美| 欧美日产一区二区三区在线观看| 欧美激情一区二区三区在线| 亚洲激情社区| 欧美日韩18| 一本大道久久a久久精品综合| 一本色道久久99精品综合 | 免费在线观看一区二区| 精品99一区二区三区| 久久人人爽爽爽人久久久| 欧美电影在线观看完整版| 亚洲日韩视频| 欧美香蕉视频| 性欧美大战久久久久久久免费观看| 久久精品毛片| 亚洲国产欧美一区二区三区久久| 蜜臀av性久久久久蜜臀aⅴ| 欧美激情影音先锋| 亚洲综合国产精品| 国产综合久久久久久| 免费久久精品视频| 妖精视频成人观看www| 久久精品日产第一区二区| 亚洲电影在线观看| 欧美日韩视频在线一区二区| 午夜视频一区在线观看| 亚洲高清色综合| 欧美一区二区黄色| 亚洲高清视频在线| 国产精品―色哟哟| 免费亚洲电影在线观看| 亚洲视频免费| 麻豆成人在线| 亚洲欧美日韩天堂一区二区| 一区二区三区在线高清| 欧美日韩国产成人精品| 欧美一区二视频| 亚洲三级电影全部在线观看高清| 欧美在线黄色| a91a精品视频在线观看| 国产亚洲一区二区在线观看| 欧美日韩精品免费观看视一区二区 | 欧美一区二区精品| 亚洲区国产区| 国产亚洲欧洲一区高清在线观看| 欧美刺激性大交免费视频| 亚洲欧美中文另类| 9久草视频在线视频精品| 免费人成网站在线观看欧美高清| 亚洲在线免费观看| 亚洲精品美女在线观看播放| 国产欧美亚洲日本| 欧美日韩精品免费观看视一区二区| 久久精品国产96久久久香蕉| 亚洲深夜激情| 亚洲蜜桃精久久久久久久 | 久久人人97超碰精品888| 欧美一区二区三区啪啪| 一本久久青青| 日韩视频一区二区| 亚洲高清视频的网址| 国产亚洲精品成人av久久ww| 欧美亚洲成人网| 欧美私人网站| 欧美日韩少妇|