析构函数何时被调用

析构函数何时被调用析构函数何时被调用析构函数在下边 3 种情况时被调用 对象生命周期结束 被销毁时 主动调用 delete 对象 i 是对象 o 的成员 o 的析构函数被调用时 对象 i 的析构函数也被调用 第一种情况 include lt iostream gt usingnamespa classA public A co

析构函数何时被调用

析构函数在下边3种情况时被调用:

  1. 对象生命周期结束,被销毁时;
  2. 主动调用delete ;
  3. 对象i是对象o的成员,o的析构函数被调用时,对象i的析构函数也被调用。

第一种情况

#include 
    using namespace std; class A { public: A() { cout << "constructing A" << endl; } ~A() { cout << "destructing A" << endl; } private: int a; }; void main() { A a; }

运行结果:

constructing A destructing A

第二种情况

如果是new的对象,即使离开了作用域也会一直存在,必须主动delete,否则只有在结束程序时才会执行析构。这里在说下内存泄漏,举个例子

#include 
    using namespace std; class A { public: A() { cout << "constructing A" << endl; } ~A() { cout << "destructing A" << endl; } private: int a; }; void fun() { A *a = new A(); } int main() { while (1) { fun(); } return 0; }

当离开fun时,虽然离开了作用域,但用new动态开辟空间的对象是不会析构的,你可以观察任务管理器,看到内存一直在上升。但你在其他地方确无法使用a所开辟的空间,因为a这个指针是保存在栈上的,当离开作用域后就自动析构(或者说自动消失了),但它所在分配空间是分配在堆上的,只有主动析构或程序结束,才会释放空间,也就是丢失了这块空间的地址,无法操作这块空间了 。

第三种情况

#include 
    using namespace std; class A { public: A() { cout << "constructing A" << endl; } ~A() { cout << "destructing A" << endl; } private: int a; }; class C { public: C() { cout << "constructing C" << endl; } ~C() { cout << "destructing C" << endl; } private: int c; }; class B : public A { public: B() { cout << "constructing B" << endl; } ~B() { cout << "destructing B" << endl; } private: int b; C c; }; void main() { B b; }

运行结果:

constructing A constructing C constructing B destructing B destructing C destructing A

B的析构函数调用之后,又调用了B的成员c的析构函数 。

若将上边的代码中的main()函数内容改成

 A* a = new B; delete a;

我们知道,这将不会调用class B的析构函数不会被调用,所以class C的析构函数也不会被调用。

运行结果:

constructing A constructing C constructing B destructing A

若将class A中的析构函数声明为虚函数 ,这时class B的析构函数也会被调用,例如:

#include 
    using namespace std; class A { public: A() { cout << "constructing A" << endl; } virtual ~A() { cout << "destructing A" << endl; } private: int a; }; class C { public: C() { cout << "constructing C" << endl; } ~C() { cout << "destructing C" << endl; } private: int c; }; class B : public A { public: B() { cout << "constructing B" << endl; } ~B() { cout << "destructing B" << endl; } private: int b; C c; }; void main() { A* a = new B; delete a; }

运行结果:

constructing A constructing C constructing B destructing B destructing C destructing A

此文章参考了:https://blog.csdn.net/weizhee/article/details/

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/213905.html原文链接:https://javaforall.net

(0)
上一篇 2026年3月18日 下午5:23
下一篇 2026年3月18日 下午5:23


相关推荐

  • 求和符号的定义和性质是什么_数学分级用虚线还是逗号

    求和符号的定义和性质是什么_数学分级用虚线还是逗号1.∑\sum∑的定义在数学中经常遇到多项式求和的问题,为了表述的方便,引入了求和符号来简化表述的方法,并且这样的的表述方法非常普遍,因此了解求和符号∑\sum∑及其运算性质就非常重要.看下面的和式:a1+a2+…+ana_1+a_2+…+a_na1​+a2​+…+an​表示n个数的和,为了简化表述,在1820年JosephFourier引入了定界的∑\sum∑表示法,并且得到了应用普及.上述和式表达如下:a1+a2+…+an=∑k=1naka_1+a_2

    2022年10月12日
    4
  • html使用display:inline-block实现标签右对齐,值左对齐效果。和设置div宽度,并居中显示。嵌套div的里层div文字居中显示

    html使用display:inline-block实现标签右对齐,值左对齐效果。和设置div宽度,并居中显示。嵌套div的里层div文字居中显示

    2021年7月20日
    101
  • 托马斯微积分第十一版_企业微服务第一部分

    托马斯微积分第十一版_企业微服务第一部分托马斯微积分第十一版无论您是大型企业还是小型初创企业 技术都是差异化的基础 如果企业不接受这一事实 他们就有失去市场份额的风险 并最终走向历史书籍 提供新的服务 产品或创新的创造力来改善现有服务的体验都在技术上有基础 IT 可以帮助您实现这一目标 但是 对于 IT 团队来说 任务是艰巨的 支持快速变化和创新的业务 紧跟带来价值的最新技术 同时为现有资产提供稳定和安全的环境 我们拥

    2026年3月16日
    2
  • 什么是分布式拒绝服务攻击?

    什么是分布式拒绝服务攻击?当多台机器一起运行以攻击一个目标时 就会发生分布式拒绝服务 DDoS 攻击 DDoS 攻击者通常利用僵尸网络 一组被劫持的互联网连接设备 进行大规模攻击 攻击者利用安全漏洞或设备弱点 使用命令和控制软件来控制众多设备 一旦获得控制 攻击者就可以命令他们的僵尸网络对目标进行 DDoS 攻击 在这种情况下 受感染的设备也是攻击的受害者 由受感染设备组成的僵尸网络也可能出租给其他潜在攻击者 僵尸网络通常可用于 雇佣攻击 服务 允许不熟练的用户发起 DDoS 攻击 DDoS 允许向目标发送成倍数的请求

    2026年3月17日
    2
  • 联通混改 流量大数据及增值业务或将成重点「建议收藏」

    联通混改 流量大数据及增值业务或将成重点

    2022年3月5日
    124
  • WeakHashMap类

    WeakHashMap类一代码示例importjava.util.*;publicclassWeakHashMapTest{ publicstaticvoidmain(String[]args) { WeakHashMapwhm=newWeakHashMap(); //HashMapwhm=newHashMap(); //将WeakHashM…

    2022年5月31日
    39

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号