1. 程式人生 > >也談析構:解構函式何時被呼叫

也談析構:解構函式何時被呼叫

為什麼要說“也”?用google搜尋“解構函式”是,google會說“約有81,500項符合 解構函式 的查詢結果”,我最近複習c++是有所心得,所以“也”想談談“解構函式”。我不想像教科書似的介紹它,而是從它何時被呼叫來淺談一下。

解構函式在下邊3種情況時被呼叫:
1.物件生命週期結束,被銷燬時;
2.delete指向物件的指標時,或delete指向物件的基類型別指標,而其基類虛構函式是虛擬函式時;
3.物件i是物件o的成員,o的解構函式被呼叫時,物件i的解構函式也被呼叫。

情況1請看下邊程式碼:
#include<iostream.h>
class A
{
 public:
 A()
 {
  cout<<"constructing A"<<endl;
 } 
 ~A()
 {
  cout<<"destructing A"<<endl;
 }
 private:
 int a;
};
class B: public A
{
 public:
 B()
 {
  cout<<"constructing B"<<endl;
 }
 ~B()
 {
  cout<<"destructing B"<<endl;
 }
 private:
 int b;
};

void main()
{
 B b;
}

執行結果為:

constructing A
constructing B
destructing B
destructing A

上述程式碼還說明了一件事:解構函式的呼叫順序與建構函式的呼叫順序相反。

情況2則正好說明了為什麼基類應該把解構函式宣告為虛擬函式,請先看下邊的例子:

#include<iostream.h>
class A
{
 public:
 A()
 {
  cout<<"constructing A"<<endl;
 } 
 ~A()
 {
  cout<<"destructing A"<<endl;
 }
 private:
 int a;
};
class B: public A
{
 public:
 B()
 {
  cout<<"constructing B"<<endl;
 }
 ~B()
 {
  cout<<"destructing B"<<endl;
 }
 private:
 int b;
};

void main()
{
 A* a = new B;
 delete a;
}

執行結果為:

constructing A
constructing B
destructing A

若將class A中的解構函式宣告為虛擬函式,執行結果將變成:

constructing A
constructing B
destructing B
destructing A

由此還可以看出虛擬函式還是多型的基礎,才c++中沒有虛擬函式就無法實現多型。因為不宣告成虛擬函式就不能“推遲聯編”,所以不能實現多型。這點上和java不同,java總是“推遲聯編”的,所以也剩了這些麻煩。

扯遠了,再看情況3,通過下邊程式碼表示:
#include<iostream.h>
class A
{
 public:
 A()
 {
  cout<<"constructing A"<<endl;
 }
 ~A()
 {
  cout<<"destructing A"<<endl;
 }
 private:
 int a;
};

class C
{
 public:
 C()
 {
  cout<<"constructing C"<<endl;
 }
 ~C()
 {
  cout<<"destructing C"<<endl;
 }
 private:
  int c;
};

class B: public A
{
 public:
 B()
 {
  cout<<"constructing B"<<endl;
 }
 ~B()
 {
  cout<<"destructing B"<<endl;
 }
 private:
 int b;
 C c;
};

void main()
{
 B b;
}

執行結果為:

constructing A
constructing C
constructing B
destructing B
destructing C
destructing A

b的解構函式呼叫之後,又呼叫了b的成員c的解構函式,同時再次驗證了解構函式的呼叫順序與建構函式的呼叫順序相反。

若將上邊的程式碼中的main()函式內容改成

 A* a = new B;
 delete a;
 
由情況2我們知道,這將不會呼叫class B的解構函式不會被呼叫,所以class C的解構函式也不會被呼叫。
正如我們想的,執行結果為:

constructing A
constructing C
constructing B
destructing A

俗話說溫故而知新,我卻不想做什麼師,只是希望能夠和大家分享一下對解構函式和虛解構函式的更深的認識。以上程式碼在VC++6.0上測試通過,如有疏漏或錯誤的認識請大家