Effective C++讀書筆記---構造/析構/賦值運算

五、條款05-瞭解C++默默編寫並調用哪些函數
1.class中,當C++處理過它之後,如果自己沒聲明任何函數,編譯器就會爲它聲明一個default構造函數、一個copy構造函數、一個copy assignment操作符和一個析構函數。惟有當這些函數被需要(被調用),它們纔會被編譯器創建出來。編譯器產生的析造函數是個non-virtual,除非這個class的base class自身聲明有virtual析構函數
2.如果class內含reference成員或const成員,再者其base class的copy assignment操作符聲明爲private,編譯器都會拒絕爲class生成copy assignment操作符

3.class析構函數(無論是編譯器生成、或用戶自定的)會自動調用其non-static成員變量的析構函數
六、條款06-若不相使用編譯自動生成的函數,就該明確拒絕
1.將不相使用編譯自動生成的函數聲明爲private且故意不實現它們,這樣,當客戶企圖拷貝這個class對象,編譯器會阻撓他。如果你不慎在member函數或friend函數之內那麼做,就會輪到連接器發出抱怨
2.將連接器錯誤移至編譯期是有可能的(而且那是好事,越早偵測出錯誤越好),只要將copy構造函數和copy assignment操作符聲明爲private就可以辦到,但不是在class自身,而是在一個專門爲了阻止copying動作而設計的base class內。這個base class非常簡單:
class Uncopyable
{
protected:
 Uncopyable(){}
 ~Uncopyable(){}
private:
 Uncopyable( const Uncopyable& );
 Uncopyable& operator= ( const Uncopyable& );
};
剩下的就是用class繼承自Uncopyable:
class xxx:private Uncopyable
{
};
這行得通,因爲嘗試拷貝對象時,編譯器便嘗試生成一個copy構造函數和一個copy assignment操作符,而編譯器會拒絕生成。
七、條款07-爲多態基類聲明virtual析構函數
1.如果class不含virtual函數,通常表示它並不意圖被用做一個base class。當class不企圖被當作base class,或者有的class被設計目的不是爲了具備多態性,令其析構函數爲virtual往往是個餿主意
2.polymorphic(帶多態性質的) base class應該聲明一個virtual析構函數。如果class帶有任何的virtual函數,它就應該擁有一個virtual析構函數
八、條款08-別讓異常逃離析構函數
1.析構函數絕對不要吐出異常。如果一個被析構函數調用的函數可能拋出異常,析構函數應該捕捉任何異常,然後吞下它們(不傳播)或關閉程序
2.如果客戶需要對某個操作函數運行期間拋出的異常做出反應,那麼class應該提供一個普通函數(而非在析構函數中)執行該操作
九、條款09-絕不在構造和析構過程中調用virtual函數
1.在base class構造期間,virtual函數不是virtual函數
2.derived class對象的base class構造期間,對象的類型是base class而不是derived class。不只virtual函數會被編譯器解析至base class,若使用運行期類型信息(runtime type infomation,例如dynamic_cast和type_id),也會把對象視爲base class類型,相同道理也適用於析構函數
3.由於你無法使用virtual函數從base class向下調用,在構造期間,可以籍由“令derived class將必要的構造信息向上傳遞到base class構造函數”替換之而加以彌補
十、條款10-令operator=返回一個reference to *this
1.爲了實現“連鎖賦值”,賦值操作符必須返回一個reference指向操作符的左側實參
2.這個協議也適用於所有賦值相關運算,如+=、-=、*=等
十一、條款11-在operator=中處理“自我賦值”
1.所謂“別名”就是“有一個以上的方法指稱(指涉)某對象”
2.確保當對象自我賦值時operator=有良好行爲。其中技術包括比較“來源對象”和“目標對象”的地址、精心周到的語句順序、以及copy-and-swap技術
3.確定任何一個函數如果操作一個以上的對象,而其中多個對象是同一個對象時,其行爲仍然正確
十二、條款12-複製對象時勿忘其每一個成分
1.任何時候只要你承擔起“爲derived class撰寫copying函數”的重大責任,必須很小心地也複製其base class成分。那些成分往往是private,所以你無法直接訪問它們,你應該讓derived class的copying函數調用相應的base class函數
2.copying函數應該確保複製“對象內的所有成員變量”及“所有base class成分”
3.不要嘗試以某個copying函數實現另一個copying函數。應該將共同機能放進第三個函數中,並由兩個copying函數共同調用

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章