20180306 c++ 為多型基類宣告virtual析構函式
記錄時間的基類和派生類:
class timekeeper
class atomicclock: public timekeeper;//原子鐘
class waterclock: public timekeeper;//水鐘
class wristwatch: public timekeeper;//腕表
工廠(factory)函式:返回指標指向乙個計時物件,factory函式會"返回乙個base class指標,指向新生成的derived class物件":
timekeeper* gettimekeeper();//返回乙個指標,指向乙個
//timekeeper派生類的動態分配物件
上述程式的問題在於gettimekeeper返回的指標指向乙個derived class物件。
在c++中,當derived class物件經由乙個base class指標被刪除,而該base class帶著乙個non-virtual析構函式,其結果未有定義--實際執行時通常發生的是物件的derived成分沒被銷毀。這可能形成資源洩露、敗壞之資料結構、在偵錯程式上浪費許多時間。
消除這個問題的做法很簡單:給base class乙個virtual析構函式。此後刪除derived class物件就會如你想的那般。是 的,它會銷毀整個物件,包括所有的derived class成分,
class timekeeper;
timekeeper *ptk = gettimekeeper();
...delete ptk;//現在 ,行為正確。
像timekeeper這樣的base classes除了析構函式之外通常還有其他的virtual函式(在不同的derived class中有不同的實現**),任何class只要帶有virtual函式都幾乎確定應該也有乙個virtual析構函式。
若class不含有virtual函式,通常表示它並不意圖被用作乙個base class。當class不企圖被當做base class,令其析構函式為virtual往往是個餿主意。
虛函式表(vtbl) 虛表指標(vptr)
欲實現出虛函式,物件必須攜帶某些資訊,主要用來在運動期決定哪乙個虛函式該被呼叫。這份資訊通常是由乙個所謂vptr(virtual table pointer)虛表指標指出,虛表指標指向乙個由函式指標構成的陣列,稱為虛函式表 vtbl(virtual table);每乙個帶有虛函式的類都有乙個相應的虛函式表,當物件呼叫某乙個虛函式,實際被呼叫的函式取決於該物件的虛表指標所指向的那個虛函式表--編譯器在其中尋找適當的函式指標。
無端的將所有classes的析構函式宣告為virtual,就像從未宣告它們為虛函式一樣,都是錯誤的,許多人的心得是:只有當class內含至少乙個virtual函式,才能為它宣告虛的(virtual)析構函式。
析構函式的運作方式是:最深層派生(most derived)的那個class其析構函式最先被呼叫,然後是其每乙個base class的析構函式被呼叫。
純虛函式:
在c++中我們可以將一些類的共性編寫到乙個抽象的類中叫他抽象類(abc abstract base class),這個類中必須包含乙個純虛函式,抽象類中不能定義出物件,但是可以作為其他類的基類。在抽象類中可以對純虛函式進行定義也可以不定義,但是注意純虛函式一般是通過抽象類派生出來的派生類的差異性函式原型,及不能在抽象類中實現的函式,那麼抽象類的特點為:
1、至少包含乙個純虛函式
2、純虛函式可以定義也可以不定義,但是一般是派生類之間的差異函式不能實現的函式
3、抽象類不能用於定義物件,但是可以宣告抽象類的指標和引用
4、抽象類包含析構函式、建構函式
5、純虛函式包含虛函式的所有特點,比如向上轉換時候基類指標自適應、通過虛函式表(virtual function table)
在虛函式原型中,後面加上 =0即可生成純虛函式:
virtual test(int a) = 0;
C 為多型基類宣告virtual析構函式
來自 effective c 條款07 為多型宣告virtual析構函式 當derived class物件經由乙個base class指標被刪除,而該base class帶著乙個non virtual析構函式,其結果未有定義 實際執行時通常發生的是物件的derived成分沒被銷毀,而其基類成分通常會...
為多型基類宣告virtual析構函式
書籍 effective c 中的條款7 讀書筆記 條款7的內容,可以大致總結為下面幾個問題 問題1 什麼是多型基類?問題2 為什麼要把多型基類的析構函式宣告為virtual析構函式?問題3 是不是應該把所有的類的析構函式宣告為virtual函式?下面來詳細回答上面三個問題 問題1 什麼是多型基類?...
為多型基類宣告virtual析構函式
一 中心內容 1 polymorphic 帶多型性質的 base classes應該宣告乙個virtual析構函式。如果class帶有任何virtual函式,它就應該擁有乙個virtual析構函式 2 classes的設計目的如果不是作為base classes使用,或不是為了具備多型性,就不該宣告...