虚析构函数的深度解析
程序员文章站
2024-03-21 12:44:34
...
析构函数为什么要写成虚函数,什么情况下写成虚函数,写成虚函数解决了什么问题, 解决问题的深层原理是什么?
前边都是表层,最后一个问题也困扰我了好一阵..
// Created by yanpan on 2019/5/10.
#include <iostream>
using namespace std;
class Base
{
public:
Base(){cout << "Base()" << endl;}
Base(int num): _bnum(num){cout << "Base(int)" << endl;}
void show()
{
cout << "_bnum: " << _bnum << endl;
}
~Base(){cout << "~Base()" << endl;} //none virtual destructor函数
private:
int _bnum;
};
class Derive: public Base
{
public:
Derive(){cout << "Derive()" << endl;}
Derive(int num): _dnum(num){cout << "Derive(int)" << endl;}
virtual ~Derive(){cout << "~Derive()" << endl;}
private:
int _dnum;
};
int main()
{
Base* base = new Derive();
delete base;
return 0;
}
运行结果:程序运行崩溃
崩溃的原因:调用了基类的析构函数,没有调用派生的析构函数,导致资源没有得到正确的释放。
解决的办法:实现动多态,把基类的析构函数写成虚函数 运行正确
class Base
{
public:
Base(){cout << "Base()" << endl;}
Base(int num): _bnum(num){cout << "Base(int)" << endl;}
void show()
{
cout << "_bnum: " << _bnum << endl;
}
virtual ~Base(){cout << "~Base()" << endl;}
private:
int _bnum;
};
为什么虚析构函数可以解决这个问题,写成虚函数会发生多态,多态在运行的时候才知道调用哪个函数,在运行的时候找到虚函数指针,该指针是指向派生类虚函数表,调用派生类的析构函数。派生类的析构函数调用后自动调用基类的析构函数。所以,派生类对象调用了析构后 基类随后就调用了析构函数.
问题一: 继承的时候不会继承基类的构造函数和析构函数
问题二:基类的析构函数和派生类的析构函数不是同名的函数
解答:编译器对析构函数有一个统一的命名,destructor,这样就解决了派生类虚函数表里边派生类析构函数覆盖基类的析构函数