使用新放置来更新参照杆件
Using placement new to update a reference member?
以下代码在C++中合法吗?
template<typename T>
class Foo {
public:
Foo(T& v) : v_(v) {}
private:
T& v_;
};
int a = 10;
Foo<int> f(a);
void Bar(int& a) {
new (&f)Foo<int>(a);
}
引用不应该绑定两次,对吧?
这是完全无效的。
[基本生活]/1,重点矿:
类型为
T
的对象的生存期在以下情况下结束:
- 如果
T
是具有非平凡析构函数(12.4)的类类型,则析构函数调用启动,或者- 对象占用的存储被重用或释放
放置new重用存储,结束由f
表示的对象的生命周期。
[基本生活]/7:
如果,在对象的生存期结束之后,在存储之前被占用的对象被重新使用或释放,新对象在原始对象占用的存储位置创建指向原始对象的指针,引用到原始对象,或者原始对象的名称将自动引用新对象,并且在新对象已经启动,可以用于操作新对象,如果:
- 新对象的存储正好覆盖原始对象所占用的存储位置,以及
- 新对象与原始对象的类型相同(忽略顶级cv限定符),并且
- 原始对象的类型不是const限定的,如果是类类型,则不包含任何类型为的非静态数据成员const限定或引用类型,以及
- 原始对象是类型为
T
的派生次数最多的对象(1.8),而新对象是类型T
的派生次数最少的对象(也就是说,它们是而不是基类子对象)
由于不满足第三个要点,在调用Bar
之后,f
不是指由放置new
创建的对象,而是指之前不再存在的对象,并且尝试使用它会导致未定义的行为。
另请参见CWG1776和P0137R0。
它可能是合法的,但它的风格非常糟糕。放置new的参数是一个void*,所以你告诉C++将f的地址重新解释为void*,然后用它作为位置来构建新的东西-覆盖原始的f。
基本上,不要那样做。
相关文章:
- Qt:当QListView获得新条目时,如何更新QStringList
- 如果我想在没有更新编译器的情况下使用新功能,该怎么办?
- C++:添加新结构时,结构指针向量中的所有元素都会更新
- 我可以将新的 std::tuple 放入内存映射区域,并在以后读回吗?
- C++/RapidXML:编辑节点并写入新的 XML 文件没有更新的节点
- 如何告诉VTK管道使用通过TimerEvent更新的新vtkPolyData?
- 如何在将新的 subky 添加到 HKEY_LOCAL_MACHINE\软件\类 后更新HKEY_CLASSES_R
- 需要更新Qt .pro和Visual Studio .vcxproj添加新文件
- 自 Visual Studio 15.6.2 编译器更新以来的新 C++17 [[nodiscard]] 警告是否符合标
- 使用 glUniformMatrix4fv() 用新矩阵更新旧矩阵?
- 插入新元素时结束迭代器会获得更新
- C++自动更新到新版本
- 使用WinSparkle更新新版本后,它不会自动启动应用程序
- C++,打开和编辑文本文件中的数字数据,并将结果放入新文件中
- 将 int 放入 char 数组是否在法律上需要新的放置
- 如何检查对象属性更新是否存在 std::map 键,否则插入一个新键?
- 如何在不输出新行的情况下更新终端中的输出字段
- Visual Studio C++在生成后不会更新新代码
- 在c++中自动更新新结构体中的相关值
- 只选择MySQL数据库/表中的更新/新行