條款05:Know what functions C++ silently writes and calls
1. 對一個空類,C++默認生成構造,析構,拷貝構造,和賦值(operate=)函數
2. 這些函數並不一定生成,而是在需要時,纔會被編譯器創建出來。
3. 默認的拷貝構造和賦值函數只能實現簡單的拷貝,對引用或const成員變量需要自己實現拷貝構造和賦值函數。
條款06: 若不想使用默認函數,明確的拒絕
1.通過將拷貝構造,賦值等函數聲明爲private來避免編譯器默認構造和用戶調用,如
class HomeForSale {
public:
...
private:
...
HomeForSale(const HomeForSale&); // declarations only
HomeForSale& operator=(const HomeForSale&);
};
但這樣還不能避免成員函數或friend函數的訪問,爲此可以使用這樣的基類:
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
這樣就能避免任何對HomeFroSale的拷貝構造和賦值操作。
更多的問題:
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)。
條款07:爲多態基類聲明virtual析構函數
1. 因爲 C++ 規定:當一個 derived class object(派生類對象)經由一個 base class的指針被刪除,而該base class帶有一個non virtual的析構函數,則結果是未定義的。運行時比較典型的後果是 derived part of the object(這個對象的派生部分)不會被析構。
2. 當一個類不意圖被用作一個base class的時候,不用設析構爲virtual(爲了避免引入不必要的vtbl)
如果一個類不想被實例化,但又要被當成base class,可以爲其提供一個純虛的析構函數。
這是一個例子:
class AWOV { // AWOV = "Abstract w/o Virtuals"
public:
virtual ~AWOV() = 0; // declare pure virtual destructor
};
但請注意,必須爲 pure virtual destructor(純虛擬析構函數)提供一個 definition(定義):
AWOV::~AWOV() {} // definition of pure virtual dtor
3. 如果一個類包含任何virtual函數,那應該將其析構設爲virtual;