13

给定以下代码:

class foo
{
};

class bar: public foo
{
public: 
    ~bar() { printf("~bar()\n"); }
};

class zab: public foo
{
public: 
    ~zab() { printf("~zab()\n"); }
};

struct foo_holder
{
    const foo &f;
};

int main()
{
    foo_holder holder[]= { {bar()}, {zab()} };
    printf("done!\n");
    return 0;
}

输出是:

~bar()
~zab()
done!

C++0x 有一个子句规定这可以在用作新的初始化程序时创建悬空引用,但它没有说明(至少我找不到任何东西)关于 const 临时引用的聚合初始化。

那么这是未指定的行为吗?

4

2 回答 2

1

例外列表中没有提到它,因此应该延长临时的生命周期以匹配 (array of) foo_holders 的生命周期。但是,这对我来说似乎是疏忽,也许提交缺陷报告可能是个好主意。


§12.2/5 规定,当引用绑定到临时对象时,临时对象的生命周期会延长以匹配引用的生命周期,并且因为const foo& f是 的成员foo_holder,所以引用的生命周期是匹配的生命周期foo_holder,根据 §3.7.5/ 1:

成员子对象、基类子对象和数组元素的存储时间是它们完整对象的存储时间(1.8)。

考虑到引用,这可能有点难以解释,因为 §3.8/1 指出,对象的生命周期在存储被释放或重用时结束:

T 类型对象的生命周期在以下情况下结束:

— 如果 T 是具有非平凡析构函数 (12.4) 的类类型,则析构函数调用开始,或者

——对象占用的存储空间被重用或释放。

但是,未指定引用是否使用存储;§8.3.2/4 说

未指定引用是否需要存储 (3.7)。

也许对标准有更好了解的人会更好地了解这一点。

于 2011-04-20T12:35:45.123 回答
1

我在 comp.std.c++ 上得到了答案:

http://groups.google.com/group/comp.std.c++/msg/9e779c0154d2f21b

基本上,该标准没有明确解决它;因此,它的行为应该与本地声明的引用相同。

于 2011-05-30T19:43:07.657 回答