代碼:
1 #include <iostream> 2 3 using namespace std; 4 5 class A{ 6 public: 7 A(){ 8 cout<<"construct A"<<endl; 9 } 10 virtual ~A(){ 11 cout<<"destory A"<<endl; 12 } 13 }; 14 15 class B:public A{ 16 public: 17 B(){ 18 cout<<"construct B"<<endl; 19 } 20 ~B(){ 21 cout<<"destory B"<<endl; 22 } 23 }; 24 25 class C{ 26 ~C(){ 27 cout<<"destory C"<<endl; 28 } 29 public: 30 C(){ 31 cout<<"construct C"<<endl; 32 } 33 void destory(){ 34 delete this; 35 } 36 }; 37 int main(){ 38 39 A* p = new B; 40 delete p; 41 C* p1 = new C;//new為在堆上分配空間 42 cout<<"new分配地址 "<<p1<<endl; 43 //delete p1; //編譯出錯,不能直接delete 44 p1->destory(); 45 46 //C t; //編譯出錯,構造函數為私有的 47 48 A a; 49 cout<<"不用new "<<&a<<endl; 50 51 52 return 0; 53 }
輸出:
construct A construct B destory B destory A construct C new分配地址 0x1623c20 destory C construct A 不用new 0x7ffcb2ad25b0 destory A
分析:
1、虛析構函數的作用:當基類指針指向派生類並delete時,可以調用派生類的析構函數;
2、私有析構函數的作用:令對象只能在堆上生成,即用new方法。原理是C++是一個靜態綁定語言,在編譯過程中,所有的非虛函數調用都必須分析完成(虛函數也要檢查可訪問性)。因此,當在棧上生成對象時,對象會自動析構,即析構函數必須可以訪問。而在堆上生成對象時,析構步驟由程序員控制,不一定需要析構函數。同時,此生成對象不能直接delete刪除,析構過程還需要一個專門的成員函數(代碼中的destory()函數)。
虛析構函數與抽象類結合
代碼:
1 #include <iostream> 2 #include <cstdio> 3 4 using namespace std; 5 6 class A{ 7 public: 8 //virtual ~A()=0; //如果抽象基類析構函數不需要實現,也可以用純虛析構函數,但必須在類外加以聲明 9 virtual ~A(){ 10 cout<<"destory A"<<endl; 11 } 12 virtual void func()=0; 13 }; 14 //A::~A(){} 15 16 class B:public A{ 17 public: 18 ~B(){ 19 cout<<"destory B"<<endl; 20 } 21 //virtual void func()=0; //如果不實現純虛函數,則必須重新說明,注意抽象類無法實例化 22 void func(){ 23 cout<<"this is function"<<endl; 24 } 25 }; 26 27 int main(int argc,char* argv[]){ 28 29 A* pA = new B; 30 delete pA; 31 32 return 0; 33 }
輸出:
destory B destory A