基類的析構函式需要宣告為虛函式:
當 derived class 物件經由乙個base class指標被刪除,而該base class帶著乙個non-virtual析構函式,實際執行時通常發生的是物件的derived成分沒有被銷毀。(區域性銷毀)
class base
~base()
protected:
int _b;
};class derived : public base
~derived()
protected:
int _d;
};void test()
執行結果為:
可以發現程式只刪除了base class物件,造成了區域性銷毀。
解決:將base class的析構函式生命為virtual,此後刪除derived class 物件就會銷毀整個物件,包括derived class成分。
class base
virtual ~base()
protected:
int _b;
};class derived : public base
~derived()
protected:
int _d;
};void test()
執行結果:
可以發現,如果將base class的析構函式宣告為虛函式,就不存在區域性銷毀的問題。
注: 1.任何class只要帶有 virtual 函式都幾乎應該也有乙個 virtual 析構函式。
2.如果class不含 virtual 函式,通常表示他並不意圖被用做乙個base class。當 class 不企圖被當作 base class。令其析構函式為virtual 往往是個餿主意。
1.普通函式:
普通函式只能被過載,不能被重寫,宣告為虛函式沒有任何意義,因為編譯器會在編譯時繫結函式。
2.建構函式:
因為建構函式本身就是為了明確初始化物件成員才產生的。如果建構函式是虛函式,就需要通過 vtable 來呼叫,但是此時物件還沒有例項化,無法找到 vtable ,所以不能為虛函式。
從實現上來看,vtable 是在構造函式呼叫之後才建立的,因而建構函式不能為虛函式,同時編譯器也根本無法通過編譯。
3.內聯成員函式:
因為內聯函式是為了在**中直接展開,減少函式呼叫的花費,而虛函式是為了在繼承後物件能夠準確的執行自己的動作。
而且內聯函式在編譯時被展開,虛函式在執行時才能動態繫結。
4.靜態成員函式:
靜態成員函式對於每乙個類來說只有乙份,所有的物件公用乙份**,它的實現就不是為了構成多型,也沒有要動態繫結的必要性。
5.友元函式:
因為友元函式並不支援繼承,對於沒有繼承特性的函式沒有虛函式的說法。
C 中虛函式與函式
析構函式為什麼要宣告為虛 函式?基類的析構函式需要宣告為虛函式 當派生類物件經由乙個基類指標被刪除,而該基類帶著乙個non virtual析構函式,實際執行時通常發生的是物件的派生類成員沒有被銷毀。這也就是區域性銷毀,會發生記憶體洩漏,所以我們通常將基類的析構函式需要宣告為虛函式。class bas...
C 虛函式與純虛函式
純虛函式定義如下 virtual functionname parameter 0 類的乙個成員定位虛函式的實際意義在於讓c 知道該函式並無意義,它的作用只是為了讓派生類進行函式過載保留位置。純虛函式的定義方法就是在類的虛函式後面加上 0 標記,類中一旦出現了純虛函式的定義,那麼此類為抽象類。例項 ...
C 虛函式與虛函式表
概念 虛函式 virtual function 是通過一張虛函式表 virtual table 來實現的,簡稱為v table。學習虛函式的作用 理解 c 實現多型的機制 解決了繼承 覆蓋的問題。以下摘抄自 http www.cppblog.com xczhang archive 2008 01 2...