析構函式定義為虛函式原因

2021-07-27 04:07:10 字數 1815 閱讀 5729

先看下面一段程式:

#include using namespace std;

class person

};class student : public person

};int main()

執行結果:

person::~person()

student::~student()

person::~person()

student::~student()

person::~person()

如果在基類中析構函式不加virtual,結果為:

person::~person()

person::~person()

student::~student()

person::~person()

可以看出:只有在用基類的指標指向派生類的時候,才會出現這種情況。因為這個時候虛函式發揮了動態的作用。

析構函式執行時先呼叫派生類的析構函式,其次才呼叫基類的析構函式。如果析構函式不是虛函式,而程式執行時又要通過基類的指標去銷毀派生類的動態物件,那麼用delete銷毀物件時,只呼叫了基類的析構函式,未呼叫派生類的析構函式。這樣會造成銷毀物件不完全。

如果在上面的例子中,基類中未定義virtual析構函式,而派生類中定義了virtual的析構函式,此時用基類指標指向派生類,再delete掉,

即:

class person

};class student : public person};

person * pt = new student;

delete pt;

執行結果會出錯。

反正是只要基類析構沒有定義為virtual,而派生類(可能有多層)中有把析構定義為virtual的,此時用基類的指標指向派生類,再delete,會出錯。

而:

class person

};class student : public person

};class onest : public student

};student * pt = onest;

delete pt;

執行結果為:

onest::~onest()

student::~student()

person::~person()

是可以執行的。

effective c++ (第7條:要將多型基類的析構函式宣告為虛函式)需要記住的 應該為多型基類宣告虛析構器。一旦乙個類包含虛函式,它就應該包含乙個虛析構器。 如果乙個類不用作基類或者不需具有多型性,便不應該為它宣告虛析構器。原因: 從建立講起,用gdb除錯你會發現,

(1)先呼叫父類的建構函式,再呼叫子類的建構函式,這裡有乙個問題:父類的建構函式/析構函式與子類的建構函式/析構函式會形成多型,但是當父類的建構函式/析構函式即使被宣告virtual,子類的構造/析構方法仍無法覆蓋父類的構造方法和析構方法。這是由於父類的建構函式和析構函式是子類無法繼承的,也就是說每乙個類都有自己獨有的建構函式和析構函式。

(2)而由於父類的析構函式為虛函式,所以子類會在所有屬性的前面形成虛表,而虛表內部儲存的就是父類的虛函式,即使子類也有虛函式,但是由於是單繼承,所以也只有一張虛表。

(3)當delete父類的指標時,由於子類的析構函式與父類的析構函式構成多型,如果一旦多型,即使是父類指標也要呼叫子類函式,所以得先調動子類的析構函式;之所以再調動父類的析構函式,是因為delete的機制所引起的,delete 父類指標所指的空間,要呼叫父類的析構函式。

轉處:

析構函式定義為虛函式原因

注 本文內容 於zhice163博文,感謝作者的整理。1.為什麼基類的析構函式是虛函式?在實現多型時,當用基類操作派生類,在析構時防止只析構基類而不析構派生類的狀況發生。下面 網路 源位址 a.第一段 includeusing namespace std class clxbase clxbase ...

析構函式定義為虛函式原因

先看下面一段程式 include using namespace std class person class student public person int main 執行結果 person person student student person person student studen...

析構函式定義為虛函式原因

析構函式定義為虛函式原因 先看下面一段程式 include using namespace std class person class student public person int main 執行結果 person person student student person person s...