也談析構:析構函數什麼時候被調用

爲何要說「也」?用google搜索「析構函數」是,google會說「約有81,500項符合 析構函數 的查詢結果」,我最近複習c++是有所心得,因此「也」想談談「析構函數」。我不想像教科書似的介紹它,而是從它什麼時候被調用來淺談一下。java

析構函數在下邊3種狀況時被調用:
1.對象生命週期結束,被銷燬時;
2.delete指向對象的指針時,或delete指向對象的基類類型指針,而其基類虛構函數是虛函數時;
3.對象i是對象o的成員,o的析構函數被調用時,對象i的析構函數也被調用。ios

狀況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;
};c++

void main()
{
 B b;
}函數

運行結果爲:測試

constructing A
constructing B
destructing B
destructing Agoogle

上述代碼還說明了一件事:析構函數的調用順序與構造函數的調用順序相反。指針

狀況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;
}io

運行結果爲:

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上測試經過,若有疏漏或錯誤的認識請你們指正:)  

相關文章
相關標籤/搜索