Effective C 筆記 條款07

2022-03-06 02:25:37 字數 1445 閱讀 6705

這個規則只適用於polymorphic(帶多型性質的)base class身上。這種base class的設計目的是為了用來「通過base class介面處理derived class物件」。假如我們在程式中設計factory(工廠)函式,讓它返回base class指標,指向新生成的derived class物件,假設base class有個non-virtual析構函式,當derived class物件經由乙個base class

指標被刪除,其結果未定義——實際執行時通常發生的是物件的derived成分沒有被銷毀,然而其base class成分通常會被銷毀,造成乙個詭異的「區域性銷毀」物件。

消除這個問題的做法很簡單:給base class乙個virtual析構函式。此後刪除derived class物件就會如你想要的那般。是的,它會銷毀整個物件,包括所有的derived class成分:

class timekeeper;

7:
8: timekeeper* ptk = gettimekeeper(); //返回乙個指標,指向乙個timekeeper派生類的動態分配物件
9: ...
10:

delete ptk ;

像timekeeper這樣的base class除了析構函式之外通常還有其他virtual函式,因為virtual的目的是允許derived class的實現得以客製化。任何class只要帶有virtual函式都幾乎確定也應該有乙個virtual析構函式 。

如果class不含virtual函式,通常表示它並不意圖被用作乙個多型性的base class。當class不企圖被用作多型性的base class,令其析構函式為virtual往往是個餿主意。

因此:無端地將所有classes的析構函式宣告為virtual,就像從未宣告它們為virtual一樣,都是錯誤的。正確做法:只有當class內含至少乙個virtual函式,才為它宣告virtual析構函式。

有時候令class帶有乙個pure virtual析構函式頗為便利。如果你需要你乙個abstract classes,令析構函式為 pure virtual,不僅為你提供乙個pure virtual 函式,讓你得到乙個抽象類,而且析構函式為virtual,刪除派生類物件時也不會出問題。然而這裡有個竅門:你必須為這個pure virtual析構函式提供乙份定義。析構函式的運作方式:最深層派生的那個class其析構函式最先被呼叫,然後是其每乙個base class的析構函式被呼叫。編譯器會在derived class的析構函式中建立乙個對base class析構函式的呼叫動作,所以你必須為這個函式提供乙份定義。

請記住:

(1)polymorphic(帶多型性質的)base classes應該宣告乙個virtual析構函式。如果class宣告乙個virtual函式,它就應該擁有乙個virtual析構函式。

(2)class的設計目的如果不是作為base classes使用,或不是為了具備多型,就不應該宣告virtual析構函式。

Effective C 筆記 條款11

為什麼會出現自我賦值呢?不明顯的自我賦值,是 別名 帶來的結果 所謂 別名 就是 有乙個以上的方法指涉物件 一般而言如果某段 操作pointers或references而它們被用來 指向多個相同型別的物件 就需要考慮這些物件是否為同乙個。實際上兩個物件來自同乙個繼承體系,它們甚至不需要宣告為相同型別...

Effective C 筆記 條款09

為方便採用書上的例子,先提出問題,在說解決方案。class transaction 7 8 transaction transaction base class 的建構函式之實現9 13 14 class buytransaction public transaction 假設在程式中 buytra...

Effective C 筆記 條款08

c 並不禁止析構函式吐出異常,但它不鼓勵你這樣做。考慮如下 class widget 假設這個可能吐出乙個異常5 6 7 void dosomething 8 當vector v被銷毀,它有責任銷毀其內含的所有widgets。銷毀第乙個丟擲異常,銷毀第二個丟擲異常 異常對c 而言太多了。其實,在兩個...