简单来说析构函数就是回收站。若系统不及时去回收这些垃圾(通常是无用的内存资源),那么时间越久肯定会有越来越多的垃圾。在开相同的程序,有时候手机和电脑重启了一下,速度会明显变快很多。因为RAM中的资源掉电后就释放了。
在C++中,析构函数就是释放无用资源的。在派生类中,假设用基类指针指向了一个派生类的临时变量。那么会发生什么情况。实际上这个时候只会释放基类的无用资源而没有释放这个临时的派生类的资源。
#include<iostream> usingnamespacestd; classPoint { public: Point(floatxx,floatyy){x=xx;y=yy;} virtual~Point(){cout<<"destructor of class Point"<<endl;} private: floatx,y; }; classCircle:publicPoint { public: Circle(floatr,floatxx,floatyy):Point(xx,yy),radius(r){} ~Circle(){cout<<"destructor of class Circle"<<endl;} private: floatradius; }; intmain() { Point *p=newCircle(1,0,0); deletep; return0; }
假设没有第6行的virtual关键字,就会出现下面的结果:
这就与上面所说的情况对上了,按道理程序运行结束了,new出来的那个circle临时变量也应该被回收,但是没有。这种情况在程序设计中是应该去避免的,但是这种情况一般比较隐蔽。
下面看看加了virtual关键字的运行结果。
这就是virtual的神奇之处。
在C++中,当基类的析构函数声明为虚函数时,无论指针指向了哪个类对象(同一个类族),在系统推出或是对象撤销时,系统会动态关联,调用相对应的析构函数,释放相对的空间。
在C++中,当基类的析构函数声明为虚函数时,那么该基类派生出的所有派生类的析构函数也都自动转化为虚函数。即使函数名不相同(这点很重要)。
扩展:面向对象设计中虚析构函数很重要,有时候往往我们用到了,但是还没注意到。在Qt中,例如我们定义了一个QUdpSocket的对象,我们跟踪进去发现class Q_NETWORK_EXPORT QUdpSocket : public QAbstractSocket,会发现public:
explicit QUdpSocket(QObject *parent = 0);
virtual ~QUdpSocket();
显然这里也用到了虚析构函数。