1

简单的例子:

struct A
{
   A() : i(int()) {}
   const int& i;
};

来自 gcc 的错误:

临时绑定到 'A::i' 只会持续到构造函数退出

来自 12.2p5 的规则:

临时绑定到构造函数的 ctor-initializer (12.6.2) 中的引用成员将持续存在,直到构造函数退出。

问题

有人知道这条规则的基本原理吗?在我看来,让临时人活到参考死亡会更好。

4

3 回答 3

2

我不认为扩展到对象生命周期需要证明。相反会!

临时对象的生命周期扩展仅扩展到封闭范围,这既自然又有用。这是因为我们严格控制接收引用变量的生命周期。相比之下,类成员根本不是真正的“范围内”。想象一下:

int foo();
struct Bar
{
    Bar(int const &, int const &, int const &) : /* bind */ { }
    int & a, & b, & c;
};

Bar * p = new Bar(foo(), foo(), foo());

foo()为临时人员定义有意义的寿命延长几乎是不可能的。

相反,我们有默认行为,即foo()临时的生命周期延伸到包含它的完整表达式的末尾,并且没有更多。

于 2013-01-19T22:41:35.930 回答
1

它会生活在什么样的记忆中?

为了让它按照您建议的方式工作,它不能在堆栈上,因为它必须比任何单个函数调用的寿命更长。它不能放在内存中的 struct A 之后,因为它无法知道 A 是如何分配的。

充其量,它必须变成一个秘密的堆分配。这将需要在析构函数运行时进行相应的秘密释放。复制构造函数和赋值运算符也需要秘密行为。

我不知道是否有人真正考虑过这样做。但就个人而言,对于一个相当晦涩的功能来说,这听起来过于复杂。

于 2013-01-20T00:05:33.057 回答
1

构造函数初始化列表中的 int() 在堆栈上。

一旦设置了该值, int() 就会超出范围并且引用变得无效。

于 2013-01-19T22:37:24.827 回答