C/C++中的虚析构函数和私有析构函数的使用
代码:
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