放置"new"是否可以用于更改"const"数据?
can placement "new" be used to alter "const" data?
[ 这是 memcpy() 可以用来更改 "const" 成员数据的后续吗? 声明不可变类C++习惯性方法确实解决了这个问题,尤其是这个答案"在围绕不可变数据设计的语言中,它会知道它可以"移动"你的数据,尽管它(逻辑)不可变。
与const
成员一起struct
struct point2d { const int x; const int y; }; // can't change to remove "const"
保存指向point2d
的指针的类可以指向具有不同值的新point2d
实例。
struct Bar
{
std::unique_ptr<point2d> pPt_{ new point2d{ 0, 0 } };
const point2d& pt() const {
return *pPt_;
}
void move_x(int value) {
pPt_.reset(new point2d{ pt().x + value, pt().y });
}
};
Bar
的客户看到:
Bar bar; // (0, 0)
bar.move_x(3141); // (3141, 0)
point2d
和Bar
都完全按照预期工作;是的,point2d
是完全不可变的。
但是,我真的很想要一个不同的Bar
实现,将point2d
实例存储为成员数据。 有什么办法可以做到这一点吗? 使用放置new
应该会导致未定义的行为(请参阅注释)。
#include <new>
struct Baz
{
point2d pt{ 0, 0 };
void move_x(int value) {
// ** is this undefined behavior ? **
new (&pt) point2d { pt.x + value, pt.y };
}
};
不直接使用point2d
作为成员数据可以解决(潜在?)未定义的行为吗?
struct Blarf
{
unsigned char pt_[sizeof(point2d)];
const point2d& pt() const {
return *reinterpret_cast<const point2d*>(pt_);
}
Blarf() {
new (&pt_) point2d{ 0, 0 };
}
void move_x(int value) {
new (&pt_) point2d{ pt().x + value, pt().y };
}
};
哪个是正确的?只是Blarf
?还是Baz
也可以?或者两者都不是,唯一的解决方案是Bar
?
您可以在对象的生存期结束后重用存储。生存期以析构函数调用结束。这在技术上没有任何问题。
在对象的生命周期结束后使用该对象,就像我写这个答案时给出的示例代码所做的那样
pt.~point2d();
new (&pt) point2d { pt.x + value, pt.y };
是未定义的行为。
如果您坚持使用带有const
字段的点类,则可以像这样解决方法:
void move_x( int const value )
{
auto const old_pt = pt;
pt.~point2d();
::new (&pt) point2d { old_pt.x + value, old_pt.y };
}
这可能感觉像是不必要的复杂性和可能的微效率低下,但相反,不必要的复杂性是点类。
相关文章:
- 如何定义在编译时数据未知的 const 数组
- 静态数据成员:它"const declaration / constexpr definition"起作用?
- 静态const数据成员在另一个文件中定义
- 无法将 const 数据类型传递到非 const 函数中
- 将const数据传递到无需const_cast的非const的功能
- 返回指向 const 数据成员和 'auto' 关键字的 const 指针。有点困惑
- 不能将Const数据类型分配到非Const数据类中
- 为什么我不能使用 const 更改 const 数据的值(在我的例子中为 int) const_cast
- 用于具有const数据成员的类的move和右值赋值操作符
- 如何用const数据构造自定义const_iterator
- 具有const数据成员作为类成员的对象
- 初始化类的静态非const数据成员
- 如何在c++ VS2015控制台应用程序中嵌入配置文件,而不是硬编码为const数据
- 为什么没有为包含const数据成员的类提供默认构造函数
- const数据成员
- 指向Const数据和c++列表的Const指针
- 什么名称查找规则适用于静态 const 数据成员定义中的名称
- 非静态const数据成员
- 放置"new"是否可以用于更改"const"数据?
- 为const数据创建cv::Mat标头