1. 程式人生 > >條款6:不想使用編譯器自動生成的函數,就要明確拒絕!

條款6:不想使用編譯器自動生成的函數,就要明確拒絕!

但是 con public col 調用 operator 聲明 接受 錯誤

每一個對象都是獨一無二的,如果不想其被復制,我們就希望其復制以失敗收場。
如一座房屋出售HomeForSale類:

1 HomeForSale h1;
2 HomeForSale h2;
3 HomeForSale h3(h1);//我們希望這倆語句以失敗告終
4 h1=h2;//

通常情況下,我們使用某個功能時,調用相對應的函數即可,如果這個函數沒有被定義,則編譯器會提示錯誤。但是這一情況不適用復制構造函數和賦值構造函數。因為條款5已經指出,如果你不聲明它們,而有人希望調用它們,編譯器就會替你聲明。
這就不太好了,不管我們是否聲明它們,我們定義的某個類還是支持這種copy行為,但是這是要明確禁止的!
答案的關鍵是,編譯器產出的所有函數都是public的,為阻止這些函數的出現,我們就要自行聲明其為private,這樣就阻止了編譯器私自創建其專屬版本。這樣的話別人就不可以調用它們。
一般而言這個做法不是絕對安全,因為成員函數和友函數可以調用已經聲明為private的copy特性函數。
將成員函數定義為private而不去實現它們,這一招被大家接受,在C++ iostream庫中阻止copy行為。在ios_base,basic_ios,和sentry中,無論哪個,其復制構造函數和賦值構造函數都被聲明為private而沒有定義。
但是這個錯誤出現在連接期,如果我們希望錯誤提示越早出現越好,那麽將其提前到編譯器無疑是最棒的。

 1 Uncopyable
 2 {
 3 public:
 4 
 5 protected:
 6 Uncopyable();
 7 ~Uncopyable();//基類的析構函數不一定非得是virtual
 8 
 9 private:
10 Uncopyable(const Uncopyable&);
11 Uncopyable& operator=(const Uncopyable&);
12 };
13 class HomeForSale:private Uncopyable
14 {
15 
16 };

如果基類(Uncopyable)有復制構造函數和賦值構造函數而且為private的。那麽其子類(HomeForSale)的對象如果被copy,那麽,編譯器就會創建一個復制構造函數和賦值構造函數,而且還會嘗試調用其父類版本(復制和賦值),這時,編譯器會拒絕調用,因為父類的復制和賦值是private的。

條款6:不想使用編譯器自動生成的函數,就要明確拒絕!