虚析构函数
在C++中,不能把构造函数定义为虚构造函数,因为在实例化一个对象时才会调用构造函数,且虚函数的实现,其实本质是通过一个虚函数表指针来调用的,还没有对象更没有内存空间当然无法调用了,故没有实例化一个对象之前的虚构造函数没有意义也不能实现。
但析构函数却是可以为虚函数的,且大多时候都声明为虚析构函数。这样就可以在用基类的指针指向派生类的对象在释放时,可以根据实际所指向的对象类型动态联编调用子类的析构函数,实现正确的对象内存释放。
下面我们做一个实验,请看代码:
/************************************** //Des:C++教程demo //Author:Huang //Copyright:www.dotcpp.com //Date:2017/12/27 **************************************/ #include <iostream> using namespace std; class Point { private: int x,y; int *str; public: Point(int x=0,int y=0) { this->x = x; this->y = y; str = new int[100]; } ~Point() { delete []str; cout<<"Called Point's Destructor and Deleted str!"<<endl; } }; class Circle:public Point { private: int r; int *str; public: Circle(int x,int y,int R):Point(x,y) { r = R; str = new int[100]; } ~Circle() { delete []str; cout<<"Called Circle's Destructor and Deleted str!"<<endl; } }; int main() { Point *p; p = new Circle(10,10,20); delete p; return 0; }
可以看到代码,基类中没有用virtual声明的析构函数,且基类和派生类当中都有动态内存开辟,那么我们在主函数中也动态开辟内存的方式创建一个Circle类,然后删除,之后运行后截图如下:
可以清楚的看到,仅仅调用了基类的析构函数,这样一来派生类中new出来的4*100字节的内存就会残留,造成内存泄漏!
而如果把基类中析构函数声明为virtual,则结果大有不同!这个时候多态效应出现,会先调用释放派生类的空间,然后再释放基类的内存空间,完美结束,如下图:
以上,这就是虚析构函数带来的好处,大家自行体会。
本文固定URL:https://www.dotcpp.com/course/81
C语言网提供由在职研发工程师或ACM蓝桥杯竞赛优秀选手录制的视频教程,并配有习题和答疑,点击了解:
一点编程也不会写的:零基础C语言学练课程
解决困扰你多年的C语言疑难杂症特性的C语言进阶课程
从零到写出一个爬虫的Python编程课程
只会语法写不出代码?手把手带你写100个编程真题的编程百练课程
信息学奥赛或C++选手的 必学C++课程
蓝桥杯ACM、信息学奥赛的必学课程:算法竞赛课入门课程
手把手讲解近五年真题的蓝桥杯辅导课程