C++虛函數與虛析構函數

在類中,有兩個與衆不同的成員函數,那就是構造函數和析構函數。當構造函數與析構函數遭遇繼承和多態,它們的運行狀況又會出現什麼變化呢?

多態性是在父類或各子類中執行最合適成員函數。一般來說,只會選擇父類或子類中的某一個成員函數來執行。這可給析構函數帶來了麻煩!如果有的資源是父類的構造函數申請的,有的資源是子類的構造函數申請的,而虛函數只允許程序執行父類或子類中的某一個析構函數,豈不是註定有一部分資源將無法被釋放?爲了解決這個問題,虛析構函數變得與衆不同。

下面我們就來給析構函數的前面加上保留字virtual,看看運行的結果會怎麼樣:(程序17.8)
//animal.h
#include <iostream>
using namespace std;
class Animal
{
   public:
   Animal(int w=0,int a=0);
   virtual ~Animal();//虛析構函數
   protected:
   int weight,age;
};
Animal::Animal(int w,int a)
{
   cout <<"Animal consturctor is running..." <<endl;
   weight=w;
   age=a;
}
Animal::~Animal()
{
   cout <<"Animal destructor is running..." <<endl;
}
//cat.h
#include "animal.h"
class Cat:public Animal
{
   public:
   Cat(int w=0,int a=0);
   ~Cat();
};
Cat::Cat(int w,int a):Animal(w,a)
{
      cout <<"Cat constructor is running..." <<endl;
}
Cat::~Cat()
{
   cout <<"Cat destructor is running..." <<endl;
}
//main.cpp
#include "cat.h"
int main()
{
   Animal *pa=new Cat(2,1);
   Cat *pc=new Cat(2,4);
   cout <<"Delete pa:" <<endl;
   delete pa;
   cout <<"Delete pc:" <<endl;
   delete pc;
   return 0;
}

運行結果:
Animal consturctor is running...
Cat constructor is running...
Animal consturctor is running...
Cat constructor is running...
Delete pa:
Cat destructor is running...
Animal destructor is running...
Delete pc:
Cat destructor is running...
Animal destructor is running...

我們驚訝地發現,虛析構函數不再是運行父類或子類的某一個析構函數,而是先運行合適的子類析構函數,再運行父類析構函數。即兩個類的析構函數都被執行了,如果兩塊資源分別是由父類構造函數和子類構造函數申請的,那麼使用了虛析構函數之後,兩塊資源都能被及時釋放。

我們修改程序17.8,將Animal類析構函數前的virtual去掉,會發現運行結果中刪除pa指向的Cat對象時,不執行Cat類的析構函數。如果這時Cat類的構造函數裏申請了內存資源,就會造成內存泄漏了。

所以說,虛函數與虛析構函數的作用是不同的。虛函數是爲了實現多態,而虛析構函數是爲了同時運行父類和子類的析構函數,使資源得以釋放。


原文:http://see.xidian.edu.cn/cpp/biancheng/view/96.html

發佈了17 篇原創文章 · 獲贊 7 · 訪問量 19萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章