提问人:user541686 提问时间:1/14/2014 最后编辑:templatetypedefuser541686 更新时间:1/16/2014 访问量:2069
像这样的 C++ 中的“重新绑定”引用合法吗?
Is "rebinding" references in C++ like this legal?
问:
以下内容在 C++ 中合法吗?
据我所知,有一个微不足道的析构函数,所以它应该是合法的。
但我认为参考资料不能合法地反弹......他们可以吗?Reference
template<class T>
struct Reference
{
T &r;
Reference(T &r) : r(r) { }
};
int main()
{
int x = 5, y = 6;
Reference<int> r(x);
new (&r) Reference<int>(y);
}
答:
您不是在重新绑定参照,而是在另一个对象的内存中创建一个新对象,并放置一个新对象。由于从未运行过旧对象的析构函数,我认为这将是未定义的行为。
评论
在您的示例中没有提到反弹。第一个引用(构造在第二行,名称为 )在其整个生命周期内都绑定到 by 表示。当第三行的放置 new 表达式重用其包含对象的存储时,此引用的生存期将结束。替换对象包含一个引用,该引用在其整个生存期内受到约束,一直持续到其作用域的末尾 - 结束。r.r
int
x
y
main
评论
main
r
main
我想我在“引用”下面的一段话中找到了答案,该段落谈到了琐碎的 dtor / dtor 副作用,即 [basic.life]/7:
如果在对象的生存期结束后,在重新使用或释放该对象所占用的存储之前,则在原始对象占用的存储位置创建一个新对象,指向原始对象的指针、引用原始对象的引用或原始对象的名称将自动引用新对象,并且, 新对象的生存期开始后,可以 用于操作新对象,如果:
新对象的存储完全覆盖了原始对象占用的存储位置,并且
新对象与原始对象的类型相同(忽略顶级 cv 限定符),并且
原始对象的类型不是 const 限定的,如果是类类型,则不包含其类型为 const 限定的任何非静态数据成员或引用类型,并且
原始对象是 Type 最派生的对象,而 New 对象是 Type 的派生对象(即,它们不是基类子对象)。
T
T
通过重用存储,我们结束了原始对象的生存期 [basic.life]/1
类型对象的生存期在以下情况下结束:
T
如果是具有非平凡析构函数的类类型,则析构函数调用将启动,或者
T
对象占用的存储被重用或释放。
所以我认为 [basic.life]/7 涵盖了这种情况
Reference<int> r(x);
new (&r) Reference<int>(y);
其中,我们结束用 表示的对象的生存期,并在同一位置创建一个新对象。r
与具有引用数据成员的类类型一样,不满足 [basic.life]/7 的要求。也就是说,甚至可能不引用新对象,我们可能不会使用它来“操作”这个新创建的对象(我也将此“操作”解释为只读访问)。Reference<int>
r
评论
r.~Reference<int>()