C++虚析构函数和纯虚析构函数

    技术2026-09-20  5

    1、为什么要使用虚析构函数

    我们知道析构函数是在对象生命周期结束时自动被调用,用来做一些清理工作(如释放句柄,释放堆内存等),防止出现内存泄漏。

    那怎么还有虚析构函数呢?

    使用虚析构函数的类一般是要作为基类,被其他类继承。通过把基类的析构函数声明为虚函数,就可以通过父类指针来释放子类对象,从而完成子类的一些清理工作,防止出现内存泄漏。

    案例1:基类析构函数为非虚函数

    //test.h class Parent { public: Parent(); ~Parent(); private: int *p_ptr; }; class Child : public Parent { public: Child(); ~Child(); private: int *c_ptr; }; //test.cpp #include "test.h" #include <iostream> using namespace std; Parent::Parent() { p_ptr=new int; *p_ptr=10; } Parent::~Parent() { cout << "Parent::~Parent() was called." << endl; if(p_ptr != 0) { delete p_ptr; p_ptr=0; } } Child::Child() { c_ptr=new int; *c_ptr=20; } //main.cpp #include "test.h" void func(Parent *parent) { delete parent;//通过父类指针来释放子类对象 } int main(int argc, char *argv[]) { Child *child=new Child; func(child); return 1; }

    运行结果:

    Parent::~Parent() was called. 结论:父类析构函数为非虚函数时,通过父类指针来释放子类对象时,只会调用父类的析构函数,而不会调用子类的析构函数,造成了子类的内存泄漏。所以,应该将父类的析构函数声明为虚函数。

    案例2:父类的析构函数为虚函数

    其他文件不用动,只需修改test.h,将父类的析构函数声明为虚函数。

    //test.h class Parent { public: Parent(); virtual ~Parent();//虚析构函数 private: int *p_ptr; }; class Child : public Parent { public: Child(); ~Child(); private: int *c_ptr; };

    运行结果:

    Child::~Child() was called. Parent::~Parent() was called. 结论:只有将父类的析构函数声明为虚析构函数时,通过父类指针释放子类对象时,会先调用子类的析构函数,然后调用父类的析构函数,不存在内存泄漏问题。

    2、纯虚析构函数

    通过上面的虚析构函数知道,C++基类的析构函数最好声明为虚机构函数,那什么时候声明为纯虚析构函数呢?

    我们知道,带有纯虚函数的类为抽象类,不能被实例化,只能被子类继承,所以当我们设计一个基类为抽象类时,可以把析构函数声明为纯虚析构函数,这样基类就是抽象类了。

    注意:纯虚析构函数也要有函数体,用来做一些基类的清理工作,防止基类出现内存泄漏。

    Processed: 0.008, SQL: 9