是否可以/ ok返回一个const引用,即使函数返回的值是该函数的局部变量?我知道一旦函数返回,本地函数就不再有效 - 但如果函数是内联的并且返回的值仅在调用者范围内使用,该怎么办?那么函数的本地应该包含在调用者堆栈框中,不是吗?
答案 0 :(得分:8)
不要指望它。即使这适用于1个编译器,它也不是标准支持的行为,并且可能会破坏其他行为。
答案 1 :(得分:6)
不,不行。局部变量在堆栈上声明,并且堆栈在方法调用之间不断变化。此外,超出范围的对象也会被破坏。始终返回本地变量的副本。
考虑以下代码:
#include <iostream>
using namespace std;
class MyClass
{
public:
MyClass() { cout << "ctor" << endl; }
~MyClass() { cout << "dtor" << endl; }
MyClass(const MyClass& r) { cout << "copy" << endl; }
};
const MyClass& Test()
{
MyClass m;
return m;
}
int main()
{
cout << "before Test" << endl;
MyClass m = Test();
cout << "after Test" << endl;
}
这将打印出来:
before Test
ctor
dtor
copy
after Test
dtor
您尝试复制的对象已调用其析构函数,可能处于无效状态。
答案 2 :(得分:4)
inline
不是保证 - 这是建议。即使您使用技巧强制内联,您也永远无法确定结果,特别是如果您想要保持便携性。
因此,不这样做。
答案 3 :(得分:1)
这样做会调用未定义的行为。
inline
只是一个建议 - __forceinline
#include <iostream>
int main()
{
{
int a = 5;
std::cout << std::hex << "0x" << &a << std::endl;
}
{
int b = 10;
std::cout << std::hex << "0x" << &b << std::endl;
}
}
我的编译器将'a'和'b'放在不同的内存地址上。 除非我开启优化。您可能会认为重新使用您的对象之前占用的内存是一种优化。
你在这里试图解决一个特殊问题吗?如果您担心这一点,还有其他方法可以减少创建的临时对象的数量。
答案 4 :(得分:1)
正如其他人所说,这是危险的。如果您的编译器支持NRVO(命名返回值优化),并且您的函数使用并返回您希望通过ref以相当简单的方式返回的局部变量,那么它也是不必要的。
NRVO允许编译器在某些条件下避免复制构造 - 通常是避免按值返回对象的主要原因。 VC ++ 8支持这一点(以前版本中的delta),它在常用代码中提供了相当多的perf diff。
答案 5 :(得分:0)
当被叫者超出范围时,该值超出范围。所以不,它消失了。
但是如果你想要一个相当难看的解决方案(并且红旗警告你你的设计可能需要重构),你可以这样做:
const MyObj& GetObj()
{
static const MyObj obj_;
return obj_;
}
...但是这个解决方案如果充满危险,特别是如果对象是可修改的,或者在多线程环境中做了一些非常重要的事情。
答案 6 :(得分:0)
inline关键字不保证该函数真正内联。不要这样做。