Meh*_*dad 38 c++ reference placement-new language-lawyer
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);
}
Run Code Online (Sandbox Code Playgroud)
Mar*_*som 18
您没有重新绑定引用,您正在另一个具有新位置的内存中创建一个新对象.由于旧对象的析构函数从未运行过,我认为这将是未定义的行为.
CB *_*ley 11
您的示例中没有引用反弹.第一个引用(在第二行上使用名称构造)在其整个生命周期中r.r
绑定到int
表示x
为.当第三行的放置新表达式重新使用其包含对象的存储时,此引用的生命周期结束.替换对象包含一个绑定y
其整个生命周期的引用,该引用一直持续到其范围的结尾 - 结束main
.
我想我在“引用的”下面的一段话中找到了答案,该段谈论了琐碎的 dtor / dtor 副作用,即 [basic.life]/7:
如果一个对象的生命周期结束后,在该对象占用的存储空间被重用或释放之前,在原对象占用的存储位置上创建一个新的对象,一个指向原对象的指针,一个指向该对象的引用引用原始对象,或者原始对象的名称将自动引用新对象,并且一旦新对象的生命周期开始,可用于操作新对象,如果:
新对象的存储完全覆盖原始对象占用的存储位置,并且
新对象与原始对象具有相同的类型(忽略顶级 cv 限定符),并且
原始对象的类型不是 const 限定的,并且如果是类类型,则不包含任何类型为 const 限定的非静态数据成员或引用类型,并且
原始对象是类型的最派生对象
T
,新对象是类型的最派生对象T
(即,它们不是基类子对象)。
通过重用存储,我们结束了原始对象的生命周期 [basic.life]/1
类型对象的生命周期
T
在以下情况结束:
如果
T
是具有非平凡析构函数的类类型,则析构函数调用开始,或者对象占用的存储被重用或释放。
所以我认为 [basic.life]/7 涵盖了这种情况
Reference<int> r(x);
new (&r) Reference<int>(y);
Run Code Online (Sandbox Code Playgroud)
我们结束 表示的对象的生命周期r
,并在同一位置创建一个新对象。
由于是具有引用数据成员的类类型,因此不满足Reference<int>
[basic.life]/7 的要求。也就是说,甚至可能不会引用新对象,并且我们可能不会使用它来“操作”这个新创建的对象(我也将这种“操作”解释为只读访问)。r
归档时间: |
|
查看次数: |
1631 次 |
最近记录: |