【发布时间】:2017-11-18 22:53:45
【问题描述】:
在 C++ 中,我们可以创建临时值,而这些临时值是有生命周期的。
所有临时对象都作为评估完整表达式的最后一步被销毁,该完整表达式(词法上)包含创建它们的点,如果创建了多个临时对象,它们将按照与创建顺序相反的顺序被销毁. ...
...
- 可以通过绑定到 const 左值引用或右值引用(C++11 起)来延长临时对象的生命周期,有关详细信息,请参阅引用初始化。
可以编写一个表达式,使得结果对象将具有相关的右值引用。可以通过分配一个非引用对象并将临时对象的内容移动到其中来删除这些依赖项,但由于额外的移动/副本,这将比仅使用临时对象效率低。
通过插入这样一个带有依赖临时对象的表达式作为函数参数,这将导致函数接收一个有效的对象。这是因为表达式已成为完整表达式的子表达式。
但是,如果要延长由同一表达式创建的对象的寿命,则表达式现在已成为完整表达式,因此我希望临时人员在最坏的情况下与最终临时人员一起生活在最好的情况下,或者只是依赖的。然而,似乎所有的中间临时对象都被销毁了,导致临时对象的寿命延长,并带有悬空的引用/指针。
我相信这个问题会变得更加重要,因为我们可以使用右值引用,而不仅仅是 const 引用。
所以我的问题是,为什么会这样?没有用例来延长依赖右值的寿命吗?还是这背后有深思熟虑?
这是我的意思的一个例子:
#include <iostream>
struct Y
{
Y() { std::cout << " Y construct\n"; }
~Y() { std::cout << " Y destruct\n"; }
};
struct X
{
Y&& y;
X(Y&& y)
: y( (std::cout << " X construct\n",
std::move(y)) ) {}
~X() { std::cout << " X destruct\n"; }
operator Y&() { return y; }
};
void use(Y& y)
{
std::cout << " use\n";
}
int main()
{
std::cout << "used within fn call\n";
use(X(Y()));
std::cout << "\nused via life extention\n";
auto&& x = X(Y());
use(x);
}
输出:
在 fn 调用中使用 Y构造 X 构造 采用 X 破坏 Y破坏 通过寿命延长使用 Y构造 X 构造 Y破坏 采用 X 破坏
【问题讨论】: