虚析构函数
在C++中,不能把构造函数定义为虚构造函数,因为在实例化一个对象时才会调用构造函数,且虚函数的实现,其实本质是通过一个虚函数表指针来调用的,还没有对象更没有内存空间当然无法调用了,故没有实例化一个对象之前的虚构造函数没有意义也不能实现。
但析构函数却是可以为虚函数的,且大多时候都声明为虚析构函数。这样就可以在用基类的指针指向派生类的对象在释放时,可以根据实际所指向的对象类型动态联编调用子类的析构函数,实现正确的对象内存释放。
下面我们做一个实验,请看代码:
/**************************************//Des:C++教程demo//Author:Huang//Copyright:www.dotcpp.com//Date:2017/12/27**************************************/#include<iostream>usingnamespacestd;classPoint{private:intx,y;int*str;public:Point(intx=0,inty=0){this->x=x;this->y=y;str=newint[100];}~Point(){delete[]str;cout<<CalledPoint'sDestructorandDeletedstr!<<endl;}};classCircle:publicPoint{private:intr;int*str;public:Circle(intx,inty,intR):Point(x,y){r=R;str=newint[100];}~Circle(){delete[]str;cout<<CalledCircle'sDestructorandDeletedstr!<<endl;}};intmain(){Point*p;p=newCircle(10,10,20);deletep;return0;}
可以看到代码,基类中没有用virtual声明的析构函数,且基类和派生类当中都有动态内存开辟,那么我们在主函数中也动态开辟内存的方式创建一个Circle类,然后删除,之后运行后截图如下:
可以清楚的看到,仅仅调用了基类的析构函数,这样一来派生类中new出来的4*100字节的内存就会残留,造成内存泄漏!
而如果把基类中析构函数声明为virtual,则结果大有不同!这个时候多态效应出现,会先调用释放派生类的空间,然后再释放基类的内存空间,完美结束,如下图:
以上,这就是虚析构函数带来的好处,大家自行体会。