程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> Effective C++(6) 如何拒絕編譯器的自動生成函數

Effective C++(6) 如何拒絕編譯器的自動生成函數

編輯:C++入門知識

問題聚焦:

如果不希望class支持某一成員函數,那麼不聲明和定義它就可以了,但是這一策略對與拷貝構造函數和重載賦值操作符並不起作用。 因為如果不聲明它們,那麼當嘗試調用它們的時候,編譯器會為你聲明和定義它們。 這顯然不是你所希望看到的。

方法:將這類你不想使用並且也不想編譯器為你聲明的函數聲明為private, 而不實現它們。 原理:
編譯器自動生成的函數都是public 聲明一個函數可以阻止編譯器自動生成該函數 令這個函數為private可以阻止人們調用它
缺陷:
member函數或friend函數可以調用它們,導致鏈接錯誤。
Demo:
class HomeForSale {
public:
    ... ...
private:
    ...
    HomeForSale(const HomeForSale&);
    HomeForSale& operator=(const HomeForSale&);
};


上面的方案雖然有一個小小的缺陷,但是還是可以讓人接受的,畢竟鏈接錯誤不是那麼的不可接受。 很多時候我們總是希望盡可能地找到錯誤,畢竟鏈接錯誤遠不如編譯錯誤那樣相對容易解決一點。 這也是這個方案可以優化的地方(盡管我覺得很多時候可以不這麼做)
方案二:在方案一的基礎上,將鏈接期錯誤移至編譯器。
先來看看demo. Demo:
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》

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved