59

可能重复:
const 引用是否会延长临时对象的寿命?
延长临时工的寿命

C++ 只允许将临时对象分配给 const 引用。它不允许分配临时对象来引用。

例如:

String& a = String("test");         // Error
const String& a = String("test");   // Ok

我到处搜索这个结果,我只看到以下答案

  1. 修改临时对象会导致无法识别的问题
  2. 修改临时对象是危险的
  3. 在某些时候,你会忘记它是一个临时变量

据说,声明后临时对象消失了。所以你不应该修改它。

如果 C++ 如此热衷于阻止修改临时对象,它应该阻止读取临时对象吧?如果临时对象消失了,那么从那里读取内容没有意义吗?可能发生权利的情况也可能涉及读取。

那为什么它一直阻止单独写入并允许读取?

请给我一个可靠的 C++ 代码解释。

请不要通过指出一些替代方案来偏离问题。请用代码给我一个可靠的答案,为什么允许 const int & 并且不允许 int & 用于临时对象。

一个说 && 在那里.. 我的问题不同.. 另一个说,改变不会反映.. 即使它是 const int & 也不会反映。例如:双a;常量 int & i = a; 一个++;不会影响我。。

4

4 回答 4

38

不允许引用临时对象的原始案例是函数参数。假设这是允许的:

void inc(double& x)
{ x += 0.1; }

int i = 0;
inc(i);

为什么不i改?

于 2012-12-11T19:24:47.997 回答
18

如果 C++ 如此热衷于阻止修改临时对象,它应该阻止读取临时对象吧?如果临时对象消失了,那么从那里读取内容没有意义吗?

不,阅读对象是完全明智的。仅仅因为它会在未来消失并不意味着现在读取数据是没有意义的。

open_file(std::string("foo.txt"));

std::string("foo.txt")是一个临时的,在调用后将停止存在,open_file()但它包含的数据在它确实存在时非常重要。

不允许临时对象绑定到非常量引用的原因实际上并不是写入临时对象的一些基本问题。事实上,在很多地方,C++ 都非常乐意允许修改临时对象:

std::string("foo") = "bar";

只是设计者认为在不启用任何类似值的情况下会导致足够多的问题(可能是由于“输出参数”的常见习语),所以他们只是做出了一个设计决定,禁止临时绑定到非 const参考。

现在使用右值引用,您可以完全执行以前禁止的操作:

void foo(int &&output) {
    output = 1;
}

foo(2);

这很好用,只是不是很有用。

于 2012-12-11T19:39:25.500 回答
6

如果您有一个复制起来非常昂贵的临时对象,您可能更愿意将 aconst&带到该对象(例如函数返回),而不是将其复制到另一个变量中以供以后使用。对临时对象进行持续引用会将该临时对象的生命周期延长到引用的生命周期,从而允许您访问任何可读状态。

不允许写入,因为一旦你想改变一个变量,你就可以拥有一个真实的实例,而不是一个仅作为非常量引用别名的临时实例。

于 2012-12-11T19:23:21.810 回答
1

这有一个合乎逻辑的原因。想一想,您在这一行中实际上想要什么:

String& a = String("test");         // Error

你想要一个参考。引用与它所引用的对象有关。就像对象的地址一样(虽然引用不是地址,但这样解释更清楚)。您实际上尝试获取类似String("test"). 但是那个对象会在下一行消失,那么如果它指向的对象不存在,它的地址有什么意义呢?a现在指向一些毫无意义的东西......

关于你的第二个问题,允许临时对象有什么意义,好吧,这没有错。例如,考虑将一个String对象传递给一个函数的情况,该函数返回一个修改后的字符串,该字符串对应于该字符串。让我们调用函数 DoubleString,而不是这样做

String s("hello ");
String s2 = DoubleString(s);

您可以使用更短、更方便的表格

String s2 = DoubleString(String("hello "));

看,临时对象String("hello ")在整行代码中都存在,这意味着它在发送到它时是完整的DoubleString。只有当整条生产线完成后才会被销毁。

于 2012-12-11T19:27:12.700 回答