<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ThinkChat2.0新版上線,更智能更精彩,支持會話、畫圖、視頻、閱讀、搜索等,送10W Token,即刻開啟你的AI之旅 廣告
                # Item 6: 如果你不想使用 compiler-generated functions(編譯器生成函數),就明確拒絕 作者:Scott Meyers 譯者:fatalerror99 (iTePub's Nirvana) 發布:http://blog.csdn.net/fatalerror99/ 房地產代理商出售房屋,服務于這樣的代理商的軟件系統自然要有一個 class(類)來表示被出售的房屋: ``` class HomeForSale { ... }; ``` 每一個房地產代理商都會很快指出,每一件房產都是獨特的——沒有兩件是完全一樣的。在這種情況下,為 HomeForSale object(對象)做一個 copy(拷貝)的想法就令人不解了。你怎么能拷貝一個獨一無二的東西呢?因此最好讓類似這種企圖拷貝 HomeForSale object(對象)的行為不能通過編譯: ``` HomeForSale h1; HomeForSale h2; HomeForSale h3(h1); // attempt to copy h1 — should // not compile! h1 = h2; // attempt to copy h2 — should // not compile! ``` 唉,防止這種編譯的方法并非那么簡單易懂。通常,如果你不希望一個 class(類)支持某種功能,你可以簡單地不聲明賦予它這種功能的函數。這個策略對于 copy constructor(拷貝構造函數)和 copy assignment operator(拷貝賦值運算符)不起作用,因為,就象 Item 5 中指出的,如果你不聲明它們,而有人又想調用它們,編譯器就會替你聲明它們。 這就限制了你。如果你不聲明 copy constructor(拷貝構造函數)或 copy assignment operator(拷貝賦值運算符),編譯器也可以替你生成它們。你的 class(類)還是會支持 copying(拷貝)。另一方面,如果你聲明了這些函數,你的 class(類)依然會支持 copying(拷貝)。而我們此時的目的卻是 prevent copying(防止拷貝)! 解決這個問題的關鍵是所有的編譯器生成的函數都是 public(公有)的。為了防止生成這些函數,你必須自己聲明它們,但是你沒有理由把它們聲明為 public(公有)的。相反,應該將 copy constructor(拷貝構造函數)和 copy assignment operator(拷貝賦值運算符)聲明為 private(私有)的。通過顯式聲明一個 member function(成員函數),可以防止編譯器生成它自己的版本,而且將這個函數聲明為 private(私有)的,可以防止別人調用它。 通常,這個方案并不十分保險,因為 member(成員)和 friend functions(友元函數)還是能夠調用你的 private 函數。換句話說,除非你十分聰明地不 define(定義)它們。那么,當有人不小心地調用了它們,在 link-time(連接時)會出現錯誤。這個竅門——聲明 member functions(成員函數)為 private 卻故意不去實現它——確實很好,在 C++ 的 iostreams 庫里,就有幾個類用此方法 prevent copying(防止拷貝)。比如,看一下你用的標準庫的實現中 ios_base,basic_ios 和 sentry 的 definitions(定義),你就會看到 copy constructor(拷貝構造函數)和 copy assignment operator(拷貝賦值運算符)被聲明為 private 而且沒有被定義的情況。 將這個竅門用到 HomeForSale 上,很簡單: ``` class HomeForSale { public: ... private: ... HomeForSale(const HomeForSale&); // declarations only HomeForSale& operator=(const HomeForSale&); }; ``` 你會注意到,我省略了 functions' parameters(函數參數)的名字。這不是必須的,只是一個普通的慣例。畢竟,函數不會被實現,更少會被用到,有什么必要指定參數名呢? 對于上面的 class definition(類定義),編譯器將阻止客戶拷貝 HomeForSale objects(對象)的企圖,如果你不小心在 member(成員)或 friend function(友元函數)中這樣做了,連接程序會提出抗議。 將 link-time error(連接時錯誤)提前到編譯時間也是可行的(早發現錯誤畢竟比晚發現好),通過不在 HomeForSale 本身中聲明 copy constructor(拷貝構造函數)和 copy assignment operator(拷貝賦值運算符)為 private,而是在一個為 prevent copying(防止拷貝)而特意設計的 base class(基類)中聲明。這個 base class(基類)本身非常簡單: ``` class Uncopyable { protected: // allow construction Uncopyable() {} // and destruction of ~Uncopyable() {} // derived objects... private: Uncopyable(const Uncopyable&); // ...but prevent copying Uncopyable& operator=(const Uncopyable&); }; ``` 為了阻止拷貝 HomeForSale objects(對象),我們現在必須讓它從 Uncopyable 繼承: ``` class HomeForSale: private Uncopyable { // class no longer ... // declares copy ctor or }; // copy assign. operator ``` 這樣做是因為,如果有人——甚至是 member(成員)或 friend function(友元函數)——試圖拷貝一個 HomeForSale objects(對象),編譯器將試圖生成一個 copy constructor(拷貝構造函數)和一個 copy assignment operator(拷貝賦值運算符)。就象 Item 12 解釋的,這些函數的 compiler-generated versions(編譯器生成版)會試圖調用 base class(基類)的相應函數,而這些調用將被拒絕,因為在 base class(基類)中,拷貝操作是 private(私有)的。 Uncopyable 的實現和使用包含一些微妙之處,比如,從 Uncopyable 繼承不必是 public(公有)的(參見 Item 32 和 39),而且 Uncopyable 的 destructor(析構函數)不必是 virtual(虛擬)的(參見 Item 7)。因為 Uncopyable 不包含數據,所以它符合 Item 39 描述的 empty base class optimization(空基類優化)的條件,但因為它是 base class(基類),此項技術的應用不能引入 multiple inheritance(多繼承)(參見 Item 40)。反過來說,multiple inheritance(多繼承)有時會使 empty base class optimization(空基類優化)失效(還是參見 Item 39)。通常,你可以忽略這些微妙之處,而且僅僅像此處演示的這樣來使用 Uncopyable,因為它的工作就像在做廣告。你還可以使用在 Boost(參見 Item 55)中的一個可用版本。那個 class(類)名為 noncopyable。那是一個好東西,我只是發現那個名字有點兒 un-(不……)嗯…… nonnatural(非自然)。 Things to Remember * 為了拒絕編譯器自動提供的機能,將相應的 member functions(成員函數)聲明為 private,而且不要給出 implementations(實現)。使用一個類似 Uncopyable 的 base class(基類)是方法之一。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看