CPP*_*PPL 1 c++ function local-variables
根据我目前的理解,粗略地说,static当执行线程离开其作用域时,(非)局部变量将被销毁。但是我发现局部变量在不同的情况下被销毁的具体点是不一样的。我一直在努力理解如何确定局部变量何时被销毁,特别是其背后的原因。(我问的可能相关问题包括:1、2、3)
给定 2 个玩具类:
class A {
public:
A() { cout << "A created\n"; }
A(const A&) { cout << "A copied\n"; }
~A() { cout << "A destroyed" << endl; }
};
class B{
public:
B() { cout << "B created\n"; }
B(const B&) { cout << "B copied\n"; }
~B() { cout << "B destroyed\n"; }
};
Run Code Online (Sandbox Code Playgroud)
B& f() {
A a;
static B b;
return b;
}
int main()
{
B b = f();
}
Run Code Online (Sandbox Code Playgroud)
这里的输出如下:
A created
B created
A destroyed
B copied
B destroyed
B destroyed
Run Code Online (Sandbox Code Playgroud)
根据我目前的理解,在示例1中,局部(非static)变量在返回引用后立即被销毁,然后被引用的对象被复制到b.
A created
B created
A destroyed
B copied
B destroyed
B destroyed
Run Code Online (Sandbox Code Playgroud)
这里的输出如下:
A created
B created
B copied
B destroyed
A destroyed
B destroyed
Run Code Online (Sandbox Code Playgroud)
这次,复制b发生在局部变量被销毁之前。
根据我的理解,对于 C++17 及更高版本,返回的g()是纯右值,而不是对象。因此,如果局部变量的销毁发生在g()创建 的纯右值之后但在复制之前(如示例 1 所示),我们将复制已被销毁的内存。因此,我将输出视为“编译器正在等待复制完成,然后再销毁局部变量”。
然而,这只是我的一个非常模糊的理解。请问幕后到底发生了什么,才能让这样的“等待”始终正常进行?
B g() {
A a;
B b;
return b;
}
int main()
{
B b = g();
}
Run Code Online (Sandbox Code Playgroud)
这里的输出如下:
A created
B created
B copied
B copied
B destroyed
A destroyed
B destroyed
B destroyed
Run Code Online (Sandbox Code Playgroud)
在这种情况下,我认为b是用来复制初始化一个临时的,然后这个临时用于复制初始化cb。即使临时变量实际上是一个对象,而不是纯右值,局部变量也会在所有这些复制之后被销毁。所以,这种情况也与示例1不同。
我正在使用 Visual Studio 2022,C++20。
函数局部变量在函数的返回值初始化后立即销毁。
在第一个示例中,该返回值只是一个引用,因此它的创建没有明显的副作用。函数返回后,b然后使用返回的引用进行初始化,因此您会在 f返回后看到“B Copy”输出。
在第二个示例中,函数的返回值是一个B对象。特别是由于纯右值的工作方式b而导致的变量。main这意味着b直接由 初始化,因此您会在返回之前g看到“B Copy”输出。 g
第三个例子涉及到异常,而且异常比较复杂,具体的机制也不是很标准化。您可以确定 的fun局部变量将在catch进入块之前被销毁,但除此之外,异常对象可能在堆栈展开期间被复制任意多次。
| 归档时间: |
|
| 查看次数: |
603 次 |
| 最近记录: |