0

0

C++中的虚析构函数有什么作用?(防止内存泄漏)

冰火之心

冰火之心

发布时间:2025-12-22 15:23:54

|

667人浏览过

|

来源于php中文网

原创

虚析构函数确保通过基类指针删除派生类对象时能正确调用派生类析构函数,避免资源泄漏;只要类可能被继承且存在多态删除场景,就必须声明为virtual,推荐写法为virtual ~Base() = default;。

c++中的虚析构函数有什么作用?(防止内存泄漏)

虚析构函数的核心作用不是直接“防止内存泄漏”,而是确保通过基类指针删除派生类对象时,能正确调用派生类的析构函数。如果没声明为虚函数,只会调用基类析构函数,导致派生类中申请的资源(如动态内存、文件句柄等)无法释放——这才是引发内存泄漏等资源泄漏的根本原因。

为什么基类析构函数需要是虚函数?

当用 基类指针指向派生类对象,并用 delete 删除时,C++ 默认按指针静态类型(即基类)决定调用哪个析构函数。若基类析构函数非虚,编译器不会进行动态绑定,派生类析构函数根本不会执行。

  • 基类析构函数非虚 → 只调用基类析构函数 → 派生类成员(如 int* p = new int[100];)未被清理 → 内存泄漏
  • 基类析构函数为虚 → 运行时根据实际对象类型调用完整析构链(派生类→基类)→ 资源逐级释放

什么情况下必须写虚析构函数?

只要类设计为“可能作为基类被继承”,且**存在多态删除场景**(即通过基类指针/引用管理派生类对象生命周期),就必须将析构函数声明为 virtual

  • 常见于接口类(纯虚函数类)、抽象基类(如 Shape, Logger
  • 即使基类没有数据成员或资源,只要用户可能用 Base* p = new Derived; + delete p;,就该加 virtual
  • 如果类明确不用于继承(比如加了 final),或从不通过基类指针删除对象,则无需虚析构

怎么正确声明和定义?

通常在基类中声明为 virtual,可以是纯虚(= 0)或带空实现;派生类析构函数会自动成为虚函数,无需显式加 virtual 关键字。

有道翻译AI助手
有道翻译AI助手

有道翻译提供即时免费的中文、英语、日语、韩语、法语、德语、俄语、西班牙语、葡萄牙语、越南语、印尼语、意大利语、荷兰语、泰语全文翻译、网页翻译、文档翻译、PDF翻

下载

立即学习C++免费学习笔记(深入)”;

  • 推荐写法:virtual ~Base() = default;(C++11起,简洁安全)
  • 也可写:virtual ~Base() { }(显式空实现)
  • 避免只声明不定义:虚析构函数必须有定义,否则链接失败

一个典型错误示例

下面代码看似正常,但会漏掉派生类资源清理:

class Base {
public:
    ~Base() { cout << "Base dtor\n"; } // ❌ 非虚 → 危险!
};
class Derived : public Base {
    int* data;
public:
    Derived() : data(new int[1000]) {}
    ~Derived() { delete[] data; cout << "Derived dtor\n"; }
};
// ...
Base* p = new Derived;
delete p; // 输出只有 "Base dtor" → data 泄漏!

改成 virtual ~Base() = default; 后,输出变为 "Derived dtor" → "Base dtor",资源正确释放。

相关专题

更多
java多态详细介绍
java多态详细介绍

本专题整合了java多态相关内容,阅读专题下面的文章了解更多详细内容。

15

2025.11.27

string转int
string转int

在编程中,我们经常会遇到需要将字符串(str)转换为整数(int)的情况。这可能是因为我们需要对字符串进行数值计算,或者需要将用户输入的字符串转换为整数进行处理。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

315

2023.08.02

int占多少字节
int占多少字节

int占4个字节,意味着一个int变量可以存储范围在-2,147,483,648到2,147,483,647之间的整数值,在某些情况下也可能是2个字节或8个字节,int是一种常用的数据类型,用于表示整数,需要根据具体情况选择合适的数据类型,以确保程序的正确性和性能。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

538

2024.08.29

c++怎么把double转成int
c++怎么把double转成int

本专题整合了 c++ double相关教程,阅读专题下面的文章了解更多详细内容。

52

2025.08.29

C++中int的含义
C++中int的含义

本专题整合了C++中int相关内容,阅读专题下面的文章了解更多详细内容。

197

2025.08.29

硬盘接口类型介绍
硬盘接口类型介绍

硬盘接口类型有IDE、SATA、SCSI、Fibre Channel、USB、eSATA、mSATA、PCIe等等。详细介绍:1、IDE接口是一种并行接口,主要用于连接硬盘和光驱等设备,它主要有两种类型:ATA和ATAPI,IDE接口已经逐渐被SATA接口;2、SATA接口是一种串行接口,相较于IDE接口,它具有更高的传输速度、更低的功耗和更小的体积;3、SCSI接口等等。

1019

2023.10.19

PHP接口编写教程
PHP接口编写教程

本专题整合了PHP接口编写教程,阅读专题下面的文章了解更多详细内容。

63

2025.10.17

php8.4实现接口限流的教程
php8.4实现接口限流的教程

PHP8.4本身不内置限流功能,需借助Redis(令牌桶)或Swoole(漏桶)实现;文件锁因I/O瓶颈、无跨机共享、秒级精度等缺陷不适用高并发场景。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

411

2025.12.29

C++ 单元测试与代码质量保障
C++ 单元测试与代码质量保障

本专题系统讲解 C++ 在单元测试与代码质量保障方面的实战方法,包括测试驱动开发理念、Google Test/Google Mock 的使用、测试用例设计、边界条件验证、持续集成中的自动化测试流程,以及常见代码质量问题的发现与修复。通过工程化示例,帮助开发者建立 可测试、可维护、高质量的 C++ 项目体系。

5

2026.01.16

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
C# 教程
C# 教程

共94课时 | 6.8万人学习

C 教程
C 教程

共75课时 | 4万人学习

C++教程
C++教程

共115课时 | 12.3万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号