標籤:
條款5 瞭解c++默默編寫並調用哪些函數
編譯器自動產生的copy 建構函式,copy賦值操作符,解構函式,建構函式,這些都是public和inline的,此處inline的意思是他們的定義都是在標頭檔當中的
假設有一個參考型別的資料成員,那麼上面的賦值操作是不對的,因為引用不能改變
條款6 如不想使用編譯器自動產生的函數,就該明確拒絕
上面的賦值建構函式,賦值操作符都可以有編譯器自動產生,為了拒絕使用上面兩種函數,可以建立一個將這種函數定義私用成員的類,從而不會使用這些函數
class Uncopyable {protected:Uncopyable(){}~Uncopyable(){}private:Uncopyable(const Uncopyable&);Uncopyable& operator=(const Uncopyable&);}class myclass: private Uncopyable{};
條款7 為多態基類聲明virtual 解構函式
應該經解構函式聲明為virtual,從而在多態調用時可以層層將各個類層次的資源析構乾淨,防止記憶體的泄露等問題
在某些類裡聲明純虛解構函式很方便。純虛函數將產生抽象類別——不能執行個體化的類(即不能建立此類型的對象)。有些時候,你想使一個類成為抽象類別, 但剛好又沒有任何純虛函數。怎麼辦?因為抽象類別是準備被用做基類的,基類必須要有一個虛解構函式,純虛函數會產生抽象類別,所以方法很簡單: 在想要成為抽象類別的類裡聲明一個純虛解構函式。
這裡是一個例子:
class awov { public: virtual ~awov() = 0; // 聲明一個純虛解構函式};
這個類有一個純虛函數,所以它是抽象的,而且它有一個虛解構函式,所以不會產生解構函式問題。但這裡還有一件事:必須提供純虛解構函式的定義:
awov::~awov() {} // 純虛解構函式的定義
這個定義是必需的,因為虛解構函式工作的方式是:最底層的衍生類別的解構函式最先被調用,然後各個基類的解構函式被調用。 這就是說,即使是抽象類別,編譯器也要產生對~awov的調用,所以要保證為它提供函數體。如果不這麼做,連結器就會檢測出來,最後還是得回去把它添上。
條款9:決不在構造析構過程中調用virtual函數
在建構函式中虛函數都不是虛函數,因此在使用多態是就會出現問題,假設首先對
條款10 為了實現連鎖賦值,賦值操作符必須返回一個引用,指向操作符左側的實參
widget& operator=(const Widget& rhs){......return *this;}
條款12:賦值對象時勿忘其每一部分 當編寫一個copying函數時,應該做到兩點:
(1)賦值所有的local變數成員
(2)調用所有base class的copying函數
因為要對一個對象進行賦值,同時也要賦值他的父類中的成員對象,但是這些成員對象有時是private的無法直接存取,這是就需要通過父類的copying函數來進行 例如:
//base classclass class1{public:class1(const class1& c);class1& operator=(const class1&);private:int p;};class1::class1(const class1& c1){this->p=c1.p;}class1& class1::operator=(const class1& c1){p=c1.p;return *this;}//derived classclass class2:public class1{public:class2(const class2&);class2& operator=(const class2&);private:int pp;};class2::class2(const class2& c2):class1(c2),pp(c2.pp){}class2& class2::operator=(const class2* c2){class1::operator=(c2);pp=c2.pp;return *this;}
Effective C++ 隨筆(2)