You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

对象析构后仍可访问、析构顺序及重复析构的技术疑问

对象析构后仍可访问、析构顺序及重复析构的技术疑问

咱们一步一步拆解你的代码和输出,把几个疑问逐个讲清楚:

1. 为什么临时Dog析构后,还能访问到animals->dog.name的值?

你这里其实混淆了两个完全不同的Dog对象:

  • 第一个是Animals结构体里的成员变量dog:它在new Animals的时候就被默认构造了(因为你没给它写初始化列表,所以调用无参的Dog(),这个构造函数没有输出日志,所以你没看到对应的记录)。这个对象从new创建出来,到delete animals执行前一直存在。
  • 第二个是赋值时创建的临时Dog对象:animals->dog = Dog("layka");这句里,Dog("layka")会创建一个临时对象,调用带参数的构造函数(输出“dog constructed”),然后把这个临时对象的内容赋值给成员dog(std::string是值类型,这里是把临时对象的name完整拷贝到成员dog的name里),之后临时对象就被销毁了(输出“dog destructed”)。

你最后访问的animals->dog.name是成员dog的name,它是临时对象name的独立拷贝,和已经销毁的临时对象完全没关系,所以自然能正常输出“layka”。

2. 为什么animal destructed在dog destructed之前输出?

这是C++类的固定析构规则:

  • 构造类对象时,先构造所有成员变量,再执行类的构造函数体。
  • 析构类对象时,先执行类的析构函数体,再按构造的逆序逐个析构成员变量。

你的Animals析构函数体里先输出了“animal destructed”,等析构函数体执行完,才会去析构它的成员dog,所以才会看到animal destructed在dog destructed前面。并不是Animal对象先被销毁,只是它的析构函数体先执行而已。

3. 为什么Dog看起来被析构了两次?

因为你总共创建了两个Dog对象:

  • 第一个是Animals的成员dog:默认构造(无输出),最后在delete animals时被析构(输出第二次“dog destructed”)。
  • 第二个是赋值时的临时Dog对象:带参数构造(输出“dog constructed”),赋值完成后立即被析构(输出第一次“dog destructed”)。

这是两个完全独立的对象,各自被析构一次,并不是同一个Dog被析构两次。

备注:内容来源于stack exchange,提问作者ArziousYi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.21 13:39:51