第15章 虛函式

2021-09-22 16:46:35 字數 1799 閱讀 3963

直接的講,c++中基類採用virtual虛析構函式是為了防止記憶體洩漏。具體地說,如果派生類中申請了記憶體空間,並在其析構函式中對這些記憶體空間進行釋放。假設基類中採用的是非虛析構函式,當刪除基類指標指向的派生類物件時就不會觸發動態繫結,因而只會呼叫基類的析構函式,而不會呼叫派生類的析構函式。那麼在這種情況下,派生類中申請的空間就得不到釋放從而產生記憶體洩漏。所以,為了防止這種情況的發生,c++中基類的析構函式應採用virtual虛析構函式。 

1. 測試**: 

#include #include using namespace std;

class base

~base()

};class derived : public base

~derived()

};int main()

輸出結果:

2. 測試**: 

#include #include using namespace std;

class base

virtual ~base() };

class derived : public base

virtual ~derived() };

int main()

輸出結果:

輸出結果:

分析:

注意,輸出不是d::f。 究竟發生了什麼?f()是在b::b()中呼叫的。如果建構函式中呼叫虛函式的規則不是如前文所述那樣,

而是如一些人希望的那樣去呼叫d::f()。那麼因為建構函式d::d()尚未執行,字串s還未初始化,所以當d::f()試圖將引數

賦給s時,結果多半是——立馬當機。

析構則正相反,遵循從繼承類到基類的順序(拆房子總得從上往下拆吧?),所以其呼叫虛函式的行為和在建構函式中一樣:虛函式此時此刻被繫結到**(當然應該是基類啦——因為繼承類已經被「拆」了——析構了!),呼叫的就是哪個函式。

有時,這條規則被解釋為是由於編譯器的實作造成的。[譯註:從實作角度可以這樣解釋:在許多編譯器中,直到構造函式呼叫完畢,vtable才被建立,此時虛函式才被動態繫結至繼承類的同名函式。] 但事實上不是這麼一回事——讓編譯器實作成「建構函式中呼叫虛函式也和從其他函式中呼叫一樣」是很簡單的[譯註:只要把vtable的建立移至構造函式呼叫之前即可]。關鍵還在於語言設計時的考量——讓虛函式可以求助於基類提供的通用**。[譯註:先有雞還是先有蛋?bjarne實際上是在告訴你,不是「先有實作再有規則」,而是「如此實作,因為規則如此」。]

演算法導論 第15章

動態規劃,就是一種求解最優解問題的。這麼說,估計大家也覺得太空泛了。想看詳細的說明,請點這裡 那麼我就講我的理解了。首先,演算法是一種策略,方法,思想,其中,有一種非常常見的常用思想 動態思想。你要做一件事情,然後,到最後完成。而你沒做一件事情都影響後面,而且你每次有很多的選擇 那麼如何每次遇到岔路...

第15章 多執行緒

模擬銀行取錢的問題 1.定義乙個account類 1 該account類封裝了賬戶編號 string 和餘額 double 兩個屬性 2 設定相應屬性的getter和setter方法 3 提供無參和有兩個引數的構造器 4 系統根據賬號判斷與使用者是否匹配,需提供hashcode 和equals 方法...

第15章 泛型

具有private構造器的類在該類外部不能new物件,也不能在外部被繼承。內部類中使用 外部類類名.this 表示外部類的this。對於乙個static方法而言,無法訪問泛型類的型別引數 class genericsetter 如果static方法想要使用泛型能力,就必須使之成為泛型方法。定義泛型方...