c++析构函数后加上virtual的原因

2023-11-07

c++析构函数后加上virtual的原因

虚函数:指向基类的指针在操作它的多态类对象时,会根据不同的类对象,调用其相应的函数,实现动态绑定。
C++析构函数加上virtual是为了防止内存泄漏。假设基类中采用的是非虚析构函数,当删除基类指针指向的派生类对象时就不会触发动态绑定,因而只会调用基类的析构函数,而不会调用派生类的析构函数。那么在这种情况下,派生类中申请的空间就得不到释放从而产生内存泄漏。所以,为了防止这种情况的发生,C++中基类的析构函数应采用virtual虚析构函数。

class Base
{
    public:
    virtual void function()
    {
        cout<<"this is Base's function"<<endl;
    }

    virtual ~Base()
    {
        cout<<"this is Base's destroy"<<endl;
    }
};

class Derived:public Base
{
    public:
    void function()
    {
        cout<<"this is Derived's function"<<endl;
    }

    ~Derived()
    {
        cout<<"this is Derived's destroy"<<endl;
    }
};

int main()
{
    Base *ptr = new Derived();
    ptr->function();
    delete ptr;
    return 0;
}
上面的代码,我先写了虚函数function,第31行就是动态绑定,而33行delete删除的是Base型基类指针,此指针是没有派生类Derived的析构函数的,所以如果不在基类的析构函数加上virtual的话,就不能动态绑定派生类的析构函数(当然析构函数的动态绑定你可以看出来跟一般函数的动态绑定相比是特殊的,析构函数的虚函数不用按照函数名来找对应的的函数)。

一句话:基类的析构函数加了virtual就可以动态绑定派生类的析构函数,这样的话,在执行多态后删除其对象,就可以在删除对象的时候执行派生类的析构函数了(当然执行基类的析构函数是一定会的)。否则不会执行派生类的析构函数。

代码输出结果:

1 this is Derived’s function
2 this is Derived’s destroy
3 this is Base’s destroy

你可以尝试一下把基类的析构函数前的virtual删掉(第9行),输出结果将是:

1 this is Derived’s function
2 this is Base’s destroy

你可以观察到,没有执行派生类的析构函数

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

c++析构函数后加上virtual的原因 的相关文章

  • IIS应用程序池回收+quartz调度

    我正在 IIS 7 5 上运行一个 Web 应用程序 它需要偶尔回收 否则内存使用情况会失控 这是我正在研究的问题 当它回收时 它实际上不会运行 直到另一个请求到来 而quartz不会运行 有没有办法让IIS在回收应用程序池后立即自动启动1
  • 在路由mvc 4中添加公司名称

    我一直在尝试为 Facebook 等用户提供在 URL 中添加公司名称的选项 http localhost 50753 MyCompany Login 我尝试过不同的网址 但没有成功 routes MapRoute name Default
  • 删除是如何工作的? [复制]

    这个问题在这里已经有答案了 可能的重复 C 编程 free 如何知道要释放多少 https stackoverflow com questions 1518711 c programming how does free know how m
  • 在 C# 中调用 C++ 库 [关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 我有很多用 C 编写的库 我想从 C 调用这些库 但是 我遇到了很多问题 我想知道是否有书籍或指南告诉我如何做到这一点 Dll导入 htt
  • std::call_once 可重入且线程安全吗?

    std call once http en cppreference com w cpp thread call once是线程安全的 但它也是可重入的吗 我使用 VS2012 调试和发布 进行的测试表明 调用std call once从单
  • Gwan C#,如何获取HTTP标头?

    我需要它来重写 url 以了解我正在处理哪个友好的 url 用于用户代理和其他东西 EDIT public class Gwan MethodImplAttribute MethodImplOptions InternalCall exte
  • 为什么'enable_if'不能用于禁用这里声明

    include
  • 一元 +/- 运算符如何可能导致“-a”或“+a”中的整数提升,“a”是算术数据类型常量/变量?

    这句看似微不足道的台词摘自我的迈克 巴纳汉和布雷迪的 C 书 第 2 8 8 2 节 http publications gbdirect co uk c book chapter2 expressions and arithmetic h
  • 使用 LINQ 更新 IEnumerable 对象的简单方法

    假设我有一个这样的业务对象 class Employee public string name public int id public string desgination public int grade List
  • 获取 boost Spirit 语法中的当前行

    我正在尝试使用 boostspirit 获取正在解析的文件的当前行 我创建了一个语法类和结构来解析我的命令 我还想跟踪在哪一行找到命令并将其解析到我的结构中 我将 istream 文件迭代器包装在 multi pass 迭代器中 然后将其包
  • 使用查询表达式对 List 进行排序

    我在使用 Linq 订购这样的结构时遇到问题 public class Person public int ID get set public List
  • 增强精神、递归和堆栈溢出

    为什么下面的代码在运行时崩溃 它会给出堆栈溢出错误 include
  • 析构函数中的异步操作

    尝试在类析构函数中运行异步操作失败 这是代码 public class Executor public static void Main var c1 new Class1 c1 DoSomething public class Class
  • 从BackgroundWorker线程更新图像UI属性

    在我正在编写的 WPF 应用程序中 我有一个 TransformedBitmap 属性 该属性绑定到 UI 上的 Image 对象 每当我更改此属性时 图像就会更新 因此显示在屏幕上的图像也会更新 为了防止在检索下一张图像时 UI 冻结或变
  • 使用 GCC 生成可读的程序集?

    我想知道如何使用GCC http en wikipedia org wiki GNU Compiler Collection在我的 C 源文件中转储机器代码的助记符版本 这样我就可以看到我的代码被编译成什么 你可以使用 Java 来做到这一
  • 从浏览器访问本地文件?

    您好 我想从浏览器访问系统的本地文件 由于涉及大量安全检查 是否可以通过某种方式实现这一目标 或使用 ActiveX 或 Java Applet 的任何其他工作环境 请帮帮我 要通过浏览器访问本地文件 您可以使用签名的 Java Apple
  • 在 OpenGL 中渲染纹理 1 到 1

    所以我想做的是使用 OpenGL 和 C 将纹理渲染到平面上 作为显示图像的一种方式 但是我需要确保在渲染纹理时没有对纹理进行任何处理 抗锯齿 插值 平滑 模糊等 这是 OpenGL 处理渲染纹理的默认方式吗 或者是否需要设置一些标志才能禁
  • 如何在 winforms 应用程序的主屏幕显示之前显示欢迎屏幕?

    我想在应用程序启动时加载欢迎屏幕 然后用户单击欢迎屏幕上的按钮 然后关闭欢迎屏幕 最后显示主屏幕 static void Main startup method being called Application EnableVisualSt
  • 通过 Tab 键浏览 XML 文档字段

    In VB NET you can move through the fields in the XML member documentation with the Tab key 这在 C 中不起作用 还有其他方法吗 除了用鼠标将光标放在
  • 使用未分配的局部变量

    我遇到了一个错误 尽管声明了变量 failturetext 和 userName 错误仍然出现 谁能帮帮我吗 Use of Unassigned local variable FailureText Use of Unassigned lo

随机推荐

  • mipi-CSI2驱动接口调试 LCD 的CLK时钟频率与显示分辨率及帧率的关系

    锋影 email 174176320 qq com 我们先来看一个公式 Mipiclock width hsync hfp hbp x height vsync vfp vbp x bus width x fps lane num 2 即m
  • 让Unity中的多个模型共用同一个材质球

    如何让Unity中的多个模型共用同一个材质球呢 下面我就来分享一下我之前在做模型的时候所使用的方法和思路 供大家学习 Unity文档中曾明确提到 尽可能的共用Material 这主要是因为渲染引擎一般会按照材质对需要渲染的对象进行排序 同一
  • SCJP认证试题(十三)

    1public class A 2 private int counter 0 3 4 public static int getInstanceCount 5 return counter 6 7 8 public A 9 counter
  • 令牌桶 客户端请求_使用刷新的令牌和cookie进行安全的客户端身份验证

    令牌桶 客户端请求 To start off this is my first article here I ve thought about writing it for a while now Ever since we planned
  • vue3.0 生命周期简介

    setup 替代 beforecreate gt use setup created gt use setup 前面加on beforeMount gt onBeforeMount mounted gt onMounted beforeUp
  • MySQL之2003错误的解决方法

    今天装了MySQL 结果发现到了晚上打开Command Line Client是已输入密码就错误 然后出现一个error2003瞬间窗口关闭 后来找了一下发现是没有开启MySQL server的原因 解决方法 在命令行输入net start
  • OpenStack的部署(六)------Neutron项目

    目录 一 CT控制节点 1 创建数据库neutron 并进行授权 2 创建用户 服务并赋权 3 注册API 4 安装提供者网络 桥接 并修改相关配置文件 5 重启相关服务 二 C1 C2计算节点操作 1 部署neutron服务 2 配置Li
  • ssh安全登录

    ssh远程登录安全协议 1 ssh keygen 一直按回车即可 2 cd home hadoop ssh 验证公钥和私钥是否生成 注意 服务器想免密登录自己也需要配置免密登录 如果执行ssh copy id hostname报命令不存在那
  • 重写QTabWidget,在标签后面添加图标按钮

    原本的QTabWidget没有支持在标签后面添加自定义的按钮的方法 想在后面添加自定义的功能按钮需要重写QTabWidget类 自己实现按钮图标的重绘和鼠标点击判断等操作 1 使用到的主要事件函数 1 void paintEvent QPa
  • scrollview嵌套recyclerview滑动冲突

    给recyclerview设置下面这个属性就行了 recycler setNestedScrollingEnabled false
  • Guns入门

    一 下载源码包 下载地址 https gitee com stylefeng guns 先将项目的guns admin sql下的SQL文件导入到数据库中 主要数据表
  • Java中常见的运行时异常

    ArithmeticException 算数运算异常 由于除数为0引起的异常 ClassCast Exception 类型转换异常 当把一个对象归为某个类 但实际上此对象并不是由这个类创建的 也不是其子类创建的 则会引起异常 ArraySt
  • Ethernet_II帧和802.3_Ethernet帧格式比较

    一 Ethernet帧格式的发展 1980 DEC Intel Xerox制订了Ethernet I的标准 1982 DEC Intel Xerox又制订了Ehternet II的标准 1982 IEEE开始研究Ethernet的国际标准8
  • 【Linux】linux进程间通信netlink socket(用户与内核通信) 二

    目录 1 netlink socket介绍 2 netlink socket特点 3 为什么引入generic netlink 4 netlink通信架构 5 相关结构体 5 1 genl family 5 2 genl ops 5 3 n
  • 如何快速合并两个有序数组?

    前言 大家好 我是来自于 华为 的 程序员小熊 今天给大家带来一道与 数组 相关的题目 这道题同时也是字节 微软和亚马逊等互联网大厂的面试题 即力扣上的第 88 题 合并两个有序数组 本文主要介绍 逆向双指针 的策略来解答此题 供大家参考
  • Windows 纤程详解

    Windows 纤程详解 在Windows2000 XP中 纤程 fiber 相当于用户级别的线程或轻进程 纤程由Win32库函数支持 对核心是不可见的 纤程可以通过SwitchToFiber显示至另一合作纤程 以实现合作纤程之间的协同 纤
  • STM32程序下载的三种方式

    今天介绍下载STM32程序的三种方式 1 J Flash下载 需要用到J link J Flash 2 MDK配置下载 需要用到J link ST link keil 3 ISP下载 需要用到FlyMcu 串口线 上面提到的硬件和软件图片如
  • 20230802-下载并安装android-studio

    下载 android studio 安装包 https developer android google cn studio 安装android studio 双击安装包 D Android Studio
  • 6.统计累积访问次数

    文章目录 核心思路 核心思路 使用窗口函数sum xx over patition by yy order by zz 当sum窗口函数没有order by时 得到的是分组后的指定列值的总和 有order by时 则是指定列值的前缀累加和
  • c++析构函数后加上virtual的原因

    c 析构函数后加上virtual的原因 虚函数 指向基类的指针在操作它的多态类对象时 会根据不同的类对象 调用其相应的函数 实现动态绑定 C 析构函数加上virtual是为了防止内存泄漏 假设基类中采用的是非虚析构函数 当删除基类指针指向的