[英]Returning const reference to local variable from a function
I have some questions on returning a reference to a local variable from a function: 我有一些关于从函数返回对局部变量的引用的问题:
class A {
public:
A(int xx)
: x(xx)
{
printf("A::A()\n");
}
};
const A& getA1()
{
A a(5);
return a;
}
A& getA2()
{
A a(5);
return a;
}
A getA3()
{
A a(5);
return a;
}
int main()
{
const A& newA1 = getA1(); //1
A& newA2 = getA2(); //2
A& newA3 = getA3(); //3
}
My questions are => 我的问题是=>
Is the implementation of getA1()
correct? getA1()
的实现是否正确? I feel it is incorrect as it is returning the address of a local variable or temporary. 我觉得这是不正确的,因为它返回局部变量的地址或临时变量。
Which of the statements in main
(1,2,3) will lead to undefined behavior? main
(1,2,3)中哪些语句会导致未定义的行为?
In const A& newA1 = getA1();
在
const A& newA1 = getA1();
does the standard guarantee that a temporary bound by a const reference will not be destroyed until the reference goes out of scope? 标准是否保证const引用的临时绑定在引用超出范围之前不会被销毁?
1. Is
getA1()
implementation correct ?1.
getA1()
实现是否正确? I feel it is incorrect as it is returning address of local variable or temporary.我觉得这是不正确的,因为它返回本地变量或临时的地址。
The only version of getAx()
that is correct in your program is getA3()
. 你的程序中
getA3()
正确的getAx()
版本是getA3()
。 Both of the others have undefined behaviour no matter how you use them later. 无论你以后如何使用它们,其他两个都有不确定的行为。
2. Which of the statements in main ( 1,2,3) will lead to undefined behavior ?
2.主要(1,2,3)中的哪些陈述会导致未定义的行为?
In one sense none of them. 从某种意义上说,没有一个。 For 1 and 2 the undefined behaviour is as a result of the bodies of the functions.
对于1和2,未定义的行为是函数体的结果。 For the last line,
newA3
should be a compile error as you cannot bind a temporary to a non const reference. 对于最后一行,
newA3
应该是编译错误,因为您不能将临时绑定到非const引用。
3. In
const A& newA1 = getA1();
3.在
const A& newA1 = getA1();
does standard guarantees that temporary bound by aconst
reference will not be destroyed until the reference goes out of scope?标准保证在引用超出范围之前,不会销毁由
const
引用临时绑定的内容吗?
No. The following is an example of that: 不。以下是一个例子:
A const & newConstA3 = getA3 ();
Here, getA3()
returns a temporary and the lifetime of that temporary is now bound to the object newConstA3
. 这里,
getA3()
返回一个临时值,该临时值的生命周期现在绑定到对象newConstA3
。 In other words the temporary will exist until newConstA3
goes out of scope. 换句话说,临时将存在,直到
newConstA3
超出范围。
Q1: Yes, this is a problem, see answer to Q2. Q1:是的,这是一个问题,请参阅Q2的回答。
Q2: 1 and 2 are undefined as they refer to local variables on the stack of getA1 and getA2. Q2:1和2是未定义的,因为它们引用了getA1和getA2堆栈上的局部变量。 Those variables go out of scope and are no longer available and worse can be overwritten as the stack is constantly changing.
这些变量超出范围并且不再可用,并且随着堆栈不断变化,可能会覆盖更糟糕的变量。 getA3 works since a copy of the return value is created and returned to the caller.
getA3起作用,因为创建了返回值的副本并将其返回给调用者。
Q3: No such guarantee exists to see answer to Q2. 问题3:对于Q2的回答,没有这样的保证。
I think the main problem is that you are not returning temporaries at all, you should 我认为主要的问题是你根本不回归临时工,你应该这样做
return A(5);
rather than 而不是
A a(5);
return a;
Otherwise you are returning local variable address, not temporary. 否则,您将返回本地变量地址,而不是临时变量。 And the temporary to const reference only works for temporaries.
而临时的const引用仅适用于临时工。
I think its explained here: temporary to const reference 我认为它在这里解释: 临时到const引用
If you will compile this on VC6 you will get this warning 如果您将在VC6上编译它,您将收到此警告
******Compiler Warning (level 1) C4172 returning address of local variable or temporary A function returns the address of a local variable or temporary object. ******编译器警告(级别1)C4172返回局部变量或临时的地址函数返回局部变量或临时对象的地址。 Local variables and temporary objects are destroyed when a function returns, so the address returned is not valid.******
函数返回时会破坏局部变量和临时对象,因此返回的地址无效。
While testing for this problem i found interesting thing (given code is working in VC6): 在测试这个问题时,我发现有趣的事情(给定的代码在VC6中工作):
class MyClass
{
public:
MyClass()
{
objID=++cntr;
}
MyClass& myFunc()
{
MyClass obj;
return obj;
}
int objID;
static int cntr;
};
int MyClass::cntr;
main()
{
MyClass tseadf;
cout<<(tseadf.myFunc()).objID<<endl;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.