当前位置: 首页 > news >正文

【Qt】【C++】虚析构函数及 virtual ~Base() = default

1. 虚析构函数的作用

虚析构函数的主要作用是避免内存泄漏。当基类指针指向子类对象时,如果基类的析构函数不是虚函数,那么在删除基类指针时,只会调用基类的析构函数,而不会调用子类的析构函数。这会导致子类的资源没有被正确释放,从而造成内存泄漏。

2. 代码

  • Test.cpp
#ifndef TEST_H
#define TEST_H#include <qdebug.h>//虚析构函数
class Base1
{
public:virtual ~Base1() { qDebug() << "Base1 del"; }virtual void show() { qDebug() << "Base1 show"; }
};class Derived1 : public Base1
{
public:~Derived1() { qDebug() << "Derived1 del"; }virtual void show() override { qDebug() << "Derived1 show"; }
};//普通析构函数
class Base2
{
public:~Base2() { qDebug() << "Base2 del"; }virtual void show() { qDebug() << "Base2 show"; }
};class Derived2 : public Base2
{
public:~Derived2() { qDebug() << "Derived2 del"; }virtual void show() override { qDebug() << "Derived2 show"; }
};#endif // TEST_H
  • main.cpp
#include "Test.h"int main(int argc, char *argv[])
{Base1* test1 = new Derived1;test1->show();delete test1;qDebug() << "";Base2* test2 = new Derived2;test2->show();delete test2;return 0;
}
  • 结果
Derived1 show
Derived1 del
Base1 delDerived2 show
Base2 del
  • 结论
    • 虚析构函数的例子中,调用了子类的析构函数
    • 正常析构函数的例子中,没有调用子类的析构函数

3. virtual ~Base() = default的作用

在 C++11 中,virtual ~base() = default 是一种显式声明默认析构函数的方式。它的主要作用是让编译器生成默认的析构函数,同时保留其虚函数的特性。这种用法在现代 C++ 编程中非常重要,尤其是在涉及继承和多态的场景中。

  • 保留虚函数特性:当基类的析构函数被声明为虚函数时,派生类的析构函数会被正确调用。这对于通过基类指针删除派生类对象至关重要。如果基类的析构函数不是虚函数,可能会导致资源泄漏。

  • 显式默认行为:使用 = default 明确表示析构函数的行为是由编译器生成的,而不是用户自定义的。这种方式可以提高代码的可读性和维护性。

  • 支持隐式移动操作:如果析构函数被用户定义(即使是空实现),编译器将不会生成隐式的移动构造函数和移动赋值运算符。而使用 = default 可以避免这一问题,保留隐式的移动操作。

4. virtual ~Base() = default 与 virtual ~base() {} 的区别

  • 性能优化= default 让编译器生成的析构函数更高效,因为它直接调用编译器内部的实现,而不是用户定义的空函数。

  • 隐式移动支持:如果使用 virtual ~base() {},编译器会认为析构函数是用户定义的,从而禁用隐式的移动构造函数和移动赋值运算符。而 = default 不会影响这些操作。

  • 代码意图清晰= default 明确表达了程序员希望使用编译器生成的默认行为,而不是自定义逻辑。

5. 代码模板

#ifndef TEST_H
#define TEST_H//虚析构函数
class Base
{
public:virtual ~Base() = default;virtual void show();
};#endif // TEST_H

文章转载自:

http://eld6phBM.dmxzd.cn
http://WZ6UPxg8.dmxzd.cn
http://pg8Bhatn.dmxzd.cn
http://KqDTPXHr.dmxzd.cn
http://GGYsVrs5.dmxzd.cn
http://FGWfCHfS.dmxzd.cn
http://Pby8vdbc.dmxzd.cn
http://mpTiHfP8.dmxzd.cn
http://VStnx4Sm.dmxzd.cn
http://ocYBAZou.dmxzd.cn
http://2RkAY9qs.dmxzd.cn
http://HDZSTNU6.dmxzd.cn
http://MQBM881o.dmxzd.cn
http://VViG7Z7p.dmxzd.cn
http://OlArTSDI.dmxzd.cn
http://NkmMEWUx.dmxzd.cn
http://f5F3aEhD.dmxzd.cn
http://NIK7G8o1.dmxzd.cn
http://pbGn5hwJ.dmxzd.cn
http://PSHdSI6h.dmxzd.cn
http://3MgcNcAp.dmxzd.cn
http://TYqulCZh.dmxzd.cn
http://jUvPmbvx.dmxzd.cn
http://yd4S4O81.dmxzd.cn
http://jc8tNJg2.dmxzd.cn
http://GF3anJhU.dmxzd.cn
http://qTqvasEp.dmxzd.cn
http://o1hAYUKa.dmxzd.cn
http://MadlcioY.dmxzd.cn
http://7z9mjpmV.dmxzd.cn
http://www.dtcms.com/a/378926.html

相关文章:

  • 马斯克访谈深度解读:机器人、AI芯片与人类文明的未来
  • 深入理解 CMake 脚本片段:文件查找、字符串替换与条件处理
  • Google Ads广告验证全攻略:如何借助动态住宅IP精准投放?
  • Linux防火墙配置指南:限制特定IP访问并允许其他所有流量
  • 使用动态IP 需要注意什么
  • 2025年- H128-Lc205. 同构字符串(哈希表)--Java版
  • 今天我们开始学习iptables防火墙
  • Android逆向学习(十一) IDA动态调试Android so文件
  • 第二篇:排序算法的简单认识【数据结构入门】
  • 嵌入式铁头山羊stm32:一文总结
  • HDFS(Hadoop 分布式文件系统)知识点梳理
  • AI幻觉的罪魁祸首
  • JVM 基础
  • 计算智能的概念和其算法的主要算法类型
  • leetcode25(有效的字母异位词)
  • [Windows] FileOptimizer v17.1.0_一款文件批量压缩工具
  • 淘宝/天猫按图搜索(拍立淘)item_search_img API接口实战指南
  • Java优选算法——二分查找
  • leetcode380:RandomizedSet - O(1)时间插入删除和获取随机元素(数组+哈希表的巧妙结合)
  • 经典蓝牙的 BR(Basic Rate(基础速率))
  • 牛客周赛 Round 108题解
  • Rocky9.0去堆叠双发arp(支持“ARP 广播双发”)
  • 「京墨」1.15.0 诗词、成语、对联、句子、诗歌…
  • AWS TechFest 2025: 风险模型的转变、流程设计的转型、生成式 AI 从实验走向实施的三大关键要素、评估生成式 AI 用例的适配度
  • 【Blender】二次元人物制作【二】:五官的制作
  • MinIO集群部署详细步骤(高性能的分布式对象存储系统)
  • 带地图的 RAG:多模态 + 地理空间 在 Elasticsearch 中
  • 使用 Spring AI Alibaba Graph 实现工作流
  • 【Debug日志 | DDP 下 BatchNorm 统计失真】
  • linux C 语言开发 (六) 程序的编辑和编译(vim、gcc)