淺談C++基類的析構函數為虛函數。本站提示廣大學習愛好者:(淺談C++基類的析構函數為虛函數)文章只能為提供參考,不一定能成為您想要的結果。以下是淺談C++基類的析構函數為虛函數正文
1、緣由:
在完成多態時, 當用基類指針操作派生類, 在析構時刻避免只析構基類而不析構派生類。
2、例子:
(1)、
#include<iostream> using namespace std; class Base{ public: Base() {}; ~Base() {cout << "Output from the destructor of class Base!" << endl;}; void DoSomething() { cout << "Do something in class Base!" << endl; }; }; class Derived : public Base{ public: Derived() {}; ~Derived() { cout << "Output from the destructor of class Derived!" << endl; }; void DoSomething() { cout << "Do something in class Derived!" << endl; }; }; int main(){ Derived* p = new Derived; p->DoSomething(); delete p; return 0; }
運轉成果:
Do something in class Derived!
Output from the destructor of class Derived!
Output from the destructor of class Base!
代碼中基類的析構函數不是虛函數,在main函數頂用繼續類的指針去操作繼續類的成員,釋放指針P的進程是:先釋放繼續類的資本,再釋放基類資本。
(2)、
#include<iostream> using namespace std; class Base{ public: Base() {}; ~Base() {cout << "Output from the destructor of class Base!" << endl;}; void DoSomething() { cout << "Do something in class Base!" << endl; }; }; class Derived : public Base{ public: Derived() {}; ~Derived() { cout << "Output from the destructor of class Derived!" << endl; }; void DoSomething() { cout << "Do something in class Derived!" << endl; }; }; int main(){ Base* p = new Derived; p->DoSomething(); delete p; return 0; }
運轉成果:
Do something in class ClxBase!
Output from the destructor of class ClxBase!
代碼中基類的析構函數異樣不是虛函數,分歧的是在main函數頂用基類的指針去操作繼續類的成員,釋放指針P的進程是:只釋放基類的資本,而沒有挪用繼續類的析構函數。 挪用DoSomething()函數履行的也是基類界說的函數。
普通情形下,如許的刪除只可以或許刪除基類對象,而不克不及刪除子類對象,構成了刪除一半抽象,形成內存洩露。
在私有繼續中,基類對派生類及其對象的操作,只能影響到那些從基類繼續上去的成員。假如想要用基類對非繼續成員停止操作,則要把基類的這個函數界說為虛函數。 析構函數天然也應當如斯:假如它想析構子類中的從新界說或新的成員及對象,固然也應當聲明為虛的。
(3)、
#include<iostream> using namespace std; class Base{ public: Base() {}; virtual ~Base() {cout << "Output from the destructor of class Base!" << endl;}; virtual void DoSomething() { cout << "Do something in class Base!" << endl; }; }; class Derived : public Base{ public: Derived() {}; ~Derived() { cout << "Output from the destructor of class Derived!" << endl; }; void DoSomething() { cout << "Do something in class Derived!" << endl; }; }; int main(){ Base* p = new Derived; p->DoSomething(); delete p; return 0; }
運轉成果:
Do something in class ClxDerived!
Output from the destructor of class ClxDerived!
Output from the destructor of class ClxBase!
代碼中基類的析構函數被界說為虛函數,在main函數頂用基類的指針去操作繼續類的成員,釋放指針P的進程是:釋放了繼續類的資本,再挪用基類的析構函數。挪用DoSomething()函數履行的也是繼續類界說的函數。
3、總結:
基類指針可以指向派生類的對象(多態性),假如刪除該指針delete p;就會挪用該指針指向的派生類析構函數,而派生類的析構函數又主動挪用基類的析構函數,如許全部派生類的對象完整被釋放。假如析構函數不被聲明成虛函數,則編譯器實行靜態綁定,在刪除基類指針時,只會挪用基類的析構函數而不挪用派生類析構函數,如許就會形成派生類對象析構不完整。所以,將析構函數聲明為虛函數是非常需要的。