0

我已经使用 TDM-GCC 4.6.1 编译器对右值引用进行了一些实验,并做出了一些我无法用理论解释的有趣观察。我希望那里的专家能帮助我解释它们。

我有一个非常简单的程序,它不处理对象而是 int 原语,并且定义了 2 个函数:foo1(通过右值引用返回局部变量)和 foo2(通过值返回局部变量)

#include <iostream>

using namespace std;

int &&foo1();
int foo2();

int main()
{

int&& variable1 = foo1();
//cout << "My name is softwarelover." << endl;
cout << "variable1 is: " << variable1 << endl; // Prints 5.
cout << "variable1 is: " << variable1 << endl; // Prints 0.

int&& variable2 = foo2();
cout << "variable2 is: " << variable2 << endl; // Prints 5.
cout << "variable2 is still: " << variable2 << endl; // Still prints 5!

return 0;
}

int &&foo1() {

int a = 5;
return static_cast<int&&>(a);
}

int foo2() {

int a = 5;
return a;
}

似乎 foo1 返回并由 variable1 接收的值在一段时间后消失了——也许是几毫秒的短暂时间。请注意,我已通过注释掉 cout 来阻止打印“我的名字是软件爱好者”。如果我允许该语句运行,结果会有所不同。它不是打印 5, 0 而是打印 0, 0。似乎是因为“cout << "My name is softwarelover." 引入了时间延迟,所以 5 变成了 0。

以上是在引用原始整数时,右值引用应该如何表现,该原始整数是通过引用返回的函数而不是按值返回?对了,为什么是0,为什么不是垃圾?

还要注意 variable2 似乎永远不会消失,无论我用 cout 打印多少次!variable2 指的是一个原始整数,它是一个函数按值返回,而不是按引用返回。

谢谢。

4

1 回答 1

5

右值引用仍然只是引用。函数返回后,对函数局部变量的引用无效。你很幸运,你的右值引用在函数调用后的任何时候都是 5,因为它在函数返回后在技术上是无效的。

编辑:我正在扩展我的答案,希望有些人会发现一些有用的额外细节。

在函数内部定义的变量是函数局部变量。该变量的生命周期仅限于声明它的函数内部。您可以将其视为在函数返回时被“销毁”,但它并没有真正被销毁。如果它是一个对象,那么它的析构函数将被调用,但保存变量的内存仍然存在。您对该变量的任何引用或指针仍指向内存中的同一位置,但该内存已被重新使用(或可能在未来某个不确定的时间被重新使用)。

旧值(在您的情况下为“5”)仍会存在一段时间,直到出现某些东西并覆盖它。没有办法知道这些值仍然存在多长时间,并且任何人都不应该依赖它们在函数返回后的任何时间内仍然存在。考虑到函数返回后对函数局部变量的任何引用(或指针)都无效。打个比方,如果你去敲门,你可能不会觉得新租户很讨人喜欢。

于 2012-09-04T16:45:44.453 回答