在C ++中,使用对临时的const
引用是有效的:
const std::string& s = std::string("abc");
std::cout << s.length() << std::endl; // valid because string instance is still alive
但如果临时是通过另一种类型的转换创建的,那么这是否成立?
例如:
struct Foo
{
~Foo()
{
cout << "Foo destructor?" << endl;
}
};
struct Bar
{
operator Foo()
{
return Foo();
}
~Bar()
{
cout << "Destructor" << endl;
}
};
Foo getFoo()
{
return Foo();
}
Bar getBar()
{
return Bar();
}
int main()
{
const Foo& f = getBar();
/* is f valid here, or is it a dangling reference? */
std::cout << "We're still in main!" << std::endl;
}
我注意到在输出 We're still in main
之前,Bar的析构函数被称为,这让我觉得Foo& f
是一个悬空引用。我是对的吗?
答案 0 :(得分:2)
函数getBar
创建一个Bar
类型的对象,并立即销毁它的副本。
Bar getBar()
{
return Bar();//the lifetime of Bar() is only on this line;
}
编辑:
对于源代码中的问题const Foo & f
是否有效;是的,因为getBar
返回一个对象副本。
在检查代码后,我发现它首先返回Bar的副本,然后将其强制转换为Foo
另外,我必须提到RVO(来自评论部分),这是编译器的优化。对象的生命周期仍由其范围{}
定义,但在这种情况下,构造在函数内部完成,并且销毁在函数外部。这种优化不适用于为变量命名,如:
Bar getBar()
{
Bar tmp_value;
return tmp_value;
}
勒兹。
答案 1 :(得分:2)
临时创建方式无关紧要。如果将const X&
或X&&
绑定到本地prvalue,则临时的生命周期将延长到引用的生命周期。