C++ 类析构是按先进后出的顺序吗?

2023-06-29 11:07:10 +08:00
 iqoo

函数中栈上定义的局部类,不会在函数外使用,有些是在块中定义的。每个类的析构顺序和定义顺序一定是正好相反吗?

1489 次点击
所在节点    程序员
10 条回复
newmlp
2023-06-29 11:31:34 +08:00
这是不是属于未定义行为,看编译器优化
tool2d
2023-06-29 11:38:54 +08:00
"具体来说,构造函数中成员初始化列表的顺序决定了成员对象的构造顺序,而析构函数的调用顺序与构造函数相反。"

网上查到的,理论上代码流程设计好,先析构后析构那个类,应该也没太大影响,不至于程序挂掉把。
exch4nge
2023-06-29 11:43:39 +08:00
语义上楼主说的对
elechi
2023-06-29 13:54:23 +08:00
是的
flyqie
2023-06-29 13:58:03 +08:00
@newmlp #1

这种应该不能算 ub 吧。。

有些时候先析构函数之间也会有从属关系,要是 ub 的话那就太可怕了。。
xylophone21
2023-06-29 14:15:13 +08:00
https://isocpp.org/wiki/faq/dtors#order-dtors-for-locals

这种问题来源比答案重要

What’s the order that local objects are destructed?
In reverse order of construction: First constructed, last destructed.

In the following example, b’s destructor will be executed first, then a’s destructor:

void userCode()
{
Fred a;
Fred b;
// ...
}
Rooger
2023-06-29 14:26:29 +08:00
C++ 类析构是按先进后出的顺序吗?
函数中栈上定义的局部类,不会在函数外使用,有些是在块中定义的。每个类的析构顺序和定义顺序一定是正好相反吗?

ChatGPT

是的,你是对的。在 C++中,局部对象的生命周期遵循先进后出( LIFO )的顺序,这被称为栈式生命周期或者作用域生命周期。

当一个局部对象在函数或者代码块中被创建时(例如通过声明或者初始化),它会在那个函数或者代码块的作用域内存在。当执行流程离开了那个作用域,局部对象就会被销毁。

对于类类型的对象,销毁过程就是调用析构函数。这意味着,最后一个被创建(也就是最先进入作用域)的对象会最先被销毁(也就是最先离开作用域)。这正好与创建对象的顺序相反。

例如:

cpp
Copy code
{
MyType a;
{
MyType b;
} // b's destructor is called here
} // a's destructor is called here

在这个例子中,a 首先被创建,然后 b 被创建。但是 b 的析构函数会首先被调用,然后才是 a 的析构函数。
justou
2023-06-29 14:27:26 +08:00
必须是那样, 利用 RAII 方式来保证一些动作得到执行
void func(){
auto socks_guard = wear_socks_guard(); // 构造时穿上袜子, 析构时脱掉袜子
auto shoes_guard = wear_shoes_guard(); // 构造时穿上鞋, 析构时脱掉鞋

// ....

// 先脱鞋
// 再脱袜子
}
leonshaw
2023-06-29 14:41:39 +08:00
类 -> 对象?
这不是 RAII 的基础么
name1991
2023-06-29 16:59:21 +08:00
ChatGPT 的答案能信吗?翻了下 c++ primer
ChatGPT 说得对!!

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/952631

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX