对象析构后仍可访问、析构顺序及重复析构的技术疑问
对象析构后仍可访问、析构顺序及重复析构的技术疑问
咱们一步一步拆解你的代码和输出,把几个疑问逐个讲清楚:
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
相关产品推荐
相关产品推荐

