問題聚焦:
如果不希望class支持某一成員函數,那麼不聲明和定義它就可以了,但是這一策略對與拷貝構造函數和重載賦值操作符並不起作用。 因為如果不聲明它們,那麼當嘗試調用它們的時候,編譯器會為你聲明和定義它們。 這顯然不是你所希望看到的。
編譯器自動生成的函數都是public 聲明一個函數可以阻止編譯器自動生成該函數 令這個函數為private可以阻止人們調用它缺陷:
member函數或friend函數可以調用它們,導致鏈接錯誤。Demo:
class HomeForSale { public: ... ... private: ... HomeForSale(const HomeForSale&); HomeForSale& operator=(const HomeForSale&); };
class Uncopyable { protected: Uncopy() {} ~Uncopy() {} private: Uncopyable (const Uncopyable&); Uncopyable& operator=(const Uncopyable&); }; // 為了阻止編譯的自動生成,我們唯一需要做的就是繼承Uncopyable class HomeForSale: private Uncopyable { ...... };
當嘗試拷貝操作時,編譯器會嘗試調用父類的對應的拷貝構造函數和重載賦值操作符,這些調用會被編譯器拒絕,因為其base class的拷貝函數是private 從而報出編譯錯誤。小結: 為了阻止編譯器的自動生成功能,可以將相應的成員函數聲明為private並且不予實現。 使用向Uncopyable這樣的base class也是一種做法。
參考資料: 《Effective C++ 3rd》