如何定义并调用基类的虚析构函数?
- 内容介绍
- 文章标签
- 相关推荐
本文共计1096个文字,预计阅读时间需要5分钟。
不添加virtual的基类析构函数,会导致派生类对象通过基类指针删除时,不执行派生类的析构逻辑——这不是内存泄漏,而是资源泄漏(例如文件句柄没关闭、动态内存没释放、锁没解锁)。这是C++多态销毁场景下最隐蔽也最危险的问题之一。
常见错误现象:delete ptr; 看似正常返回,但调试发现派生类的析构函数断点根本没命中,std::cout 语句没输出,fclose 没调用,delete[] 没执行。
- 只要类设计为被继承(哪怕当前没写派生类),且可能通过基类指针/引用管理对象生命周期,就必须声明
virtual ~Base() = default; - 如果基类已有虚函数(比如
virtual void foo();),析构函数也必须是virtual,否则行为未定义 - 纯虚析构函数可以存在,但必须提供定义(哪怕空实现):
virtual ~Base() = 0;后面得跟Base::~Base() {}
什么时候可以不写 virtual 析构函数
当类明确不作为多态基类使用时,比如:工具类(StringUtils)、仅含静态成员的类、或明确禁止继承(C++11 起用 final 修饰类)。
本文共计1096个文字,预计阅读时间需要5分钟。
不添加virtual的基类析构函数,会导致派生类对象通过基类指针删除时,不执行派生类的析构逻辑——这不是内存泄漏,而是资源泄漏(例如文件句柄没关闭、动态内存没释放、锁没解锁)。这是C++多态销毁场景下最隐蔽也最危险的问题之一。
常见错误现象:delete ptr; 看似正常返回,但调试发现派生类的析构函数断点根本没命中,std::cout 语句没输出,fclose 没调用,delete[] 没执行。
- 只要类设计为被继承(哪怕当前没写派生类),且可能通过基类指针/引用管理对象生命周期,就必须声明
virtual ~Base() = default; - 如果基类已有虚函数(比如
virtual void foo();),析构函数也必须是virtual,否则行为未定义 - 纯虚析构函数可以存在,但必须提供定义(哪怕空实现):
virtual ~Base() = 0;后面得跟Base::~Base() {}
什么时候可以不写 virtual 析构函数
当类明确不作为多态基类使用时,比如:工具类(StringUtils)、仅含静态成员的类、或明确禁止继承(C++11 起用 final 修饰类)。

