如何禁止C++預設成員函數

來源:互聯網
上載者:User

標籤:解決   拷貝構造   protect   mem   友元函數   自動產生   應用   ext   友元   

如何禁止C++預設成員函數發表於 2016-03-02   |   分類於 C++   |   閱讀次數 17前言

前幾天在一次筆試過程中被問到C++如何設計禁止調用預設建構函式,當時簡單的想法是直接將預設建構函式聲明為private即可,這樣的話對象的確不能直接調用。之後查閱了《Effective C++》之後得到了比較詳盡的解釋。

瞭解C++的預設行為

當我們建立空類時,C++預設給我們產生了四種成員函數:

  1. 建構函式
  2. 解構函式
  3. 拷貝建構函式(copy)
  4. 重載=的拷貝函數(copy assignment)

因此,當你寫下如下的代碼:

1 class Empty{};

那麼編譯器會自動產生:

class Empty{public:    Empty(){...}                              //default建構函式    Empty(const Empty& rhs){...}              //copy建構函式    ~Empty(){...}                             //解構函式    Empty& operator=(const Empty& rhs){...}   //copy assignment操作符};

至於copy建構函式和copy assignment操作符是不是有效取決於類的成員變數,例如:如果類成員有const變數或者引用,那麼是不能重新賦值的。

拒絕使用編譯器自動產生函數

書中提到了一個實際的應用情境。在房子銷售時,每一套房子都是獨一無二的(地理位置,裝修等等),那麼顯然我們不想讓別人使用拷貝建構函式或者copy assignment操作符。但是如果我們不寫,那麼編譯器會自動產生。如果我們寫了就會可能讓別人利用。那麼該怎麼辦呢?

  • 首先我們最自然的想法就是把這兩個函式宣告為私人,這樣別人調用的時候可能會報錯。我們的直覺是正確的。確實這樣做可以行得通。於是我們如此寫到:
class HomeForSale{public:    ...private:    HomeForSale(const HomeForSale& hfs){...}    HomeForSale& operator=(const HomeForSale& hfs){...}};
  • 當然那麼做並不是萬事大吉了。因為member函數和友元函數仍然能調用私人成員函數。那麼你可能又想到答案:我們無需定義成員函數,只需聲明即可:
class HomeForSale{public:    ...private:    HomeForSale(const HomeForSale&);    HomeForSale& operator=(const HomeForSale&);};

那麼member成員函數和友元函數調用時,在編譯階段沒問題,在連結階段會報錯。那麼還有沒有更好的方案能夠讓代碼在編譯階段就能檢測出錯誤呢? 答案是肯定的。

  • 我們為此建立一個基類:
class Uncopyable{protected:    Uncopyable(){}                            //允許derived對象的構造和解析    ~Uncopyable(){}private:    Uncopyable(const Uncopyable&);            //但阻止copying    Uncopyable& operator=(const Uncopyable&);};

那麼,為了阻止HomeForSale被拷貝,我們只需繼承Uncopyable:

class HomeForSale:private Uncopyable{    ...};
  • C++11提出更為簡潔的解決方案:
class HomeForSale{public:    HomeForSale(const HomeForSale&) = delete;    HomeForSale& operator=(const HomeForSale&) = delete;};
總結
  • 為駁回編譯器自動產生的成員函數,可將相應成員函式宣告為private並且不予實現。或者使用像Uncopyable這樣的基類。或者使用C++11的新特性。

  • 在boost也有這樣的基類:noncopyable。

  •  

  

如何禁止C++預設成員函數

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.