函数范围(生命周期)后,对临时对象的const引用被破坏 [英] const reference to a temporary object becomes broken after function scope (life time)
问题描述
问这个问题时,我学会了const引用临时对象在C ++中有效:
While asking this question, I learned const reference to a temporary object is valid in C++:
int main ()
{
int a = 21;
int b = 21;
//error: invalid initialization of non-const reference
//int & sum = a + b;e [...]
//OK
int const & sum = a + b;
return sum;
}
但是在下面的示例中,const引用refnop
引用了已损坏的临时对象.我想知道为什么吗?
But in the following example, the const reference refnop
refers to a destroyed temporary object. I wonder why?
#include <string>
#include <map>
struct A
{
// data
std::map <std::string, std::string> m;
// functions
const A& nothing() const { return *this; }
void init() { m["aa"] = "bb"; }
bool operator!= (A const& a) const { return a.m != m; }
};
int main()
{
A a;
a.init();
A const& ref = A(a);
A const& refnop = A(a).nothing();
int ret = 0;
if (a != ref) ret += 2;
if (a != refnop) ret += 4;
return ret;
}
使用GCC 4.1.2和MSVC 2010进行测试,返回4;
Tested using GCC 4.1.2 and MSVC 2010, it returns 4;
$> g++ -g refnop.cpp
$> ./a.out ; echo $?
4
ref
和refnop
之间的区别是对nothing()
的调用,它实际上没有任何作用.似乎在此调用之后,临时对象被破坏了!
The difference between ref
and refnop
is the call to nothing()
which does really nothing. It seems after this call, the temporary object is destroyed!
我的问题:
为什么在refnop
情况下,临时对象的生存期与其常量引用不同?
My question:
Why in the case of refnop
, the life time of the temporary object is not the same as its const reference?
推荐答案
当临时对象绑定到第一个引用时,临时对象的生存期扩展只能执行一次.此后,该引用引用了一个临时对象的知识就消失了,因此无法进一步延长生命周期.
The lifetime-extension of a temporary object can be performed only once, when the temporary object gets bound to the first reference. After that, the knowledge that the reference refers to a temporary object is gone, so further lifetime extensions are not possible.
令人困惑的案子
A const& refnop = A(a).nothing();
类似于这种情况:
A const& foo(A const& bar)
{
return bar;
}
//...
A const& broken = foo(A());
在两种情况下,临时变量都绑定到函数参数(对于nothing()
而言是隐式的this
,对于foo()
而言是bar
),并将其生存期扩展"到了函数参数的生存期.我将"extended"用引号引起来,因为临时文件的自然寿命已经更长,因此没有实际的扩展发生.
In both cases, the temporary gets bound to the function argument (the implicit this
for nothing()
, bar
for foo()
) and gets its lifetime 'extended' to the lifetime of the function argument. I put 'extended' in quotes, because the natural lifetime of the temporary is already longer, so no actual extension takes place.
由于生存期扩展属性是非传递性的,因此返回引用(恰好引用临时对象)将不会进一步延长临时对象的生存期,结果refnop
和broken
都结束指向不再存在的对象.
Because the lifetime extension property is non-transitive, returning a reference (that happens to refer to a temporary object) will not further extend the lifetime of the temporary object, with as result that both refnop
and broken
end up referring to objects that no longer exist.
这篇关于函数范围(生命周期)后,对临时对象的const引用被破坏的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!