【发布时间】:2017-08-17 06:29:12
【问题描述】:
我正在探索在 C++ 中实现真正(部分)不可变数据结构的可能性。由于 C++ 似乎没有区分变量和变量存储的对象,因此真正替换对象(无需赋值操作!)的唯一方法是使用placement new:
auto var = Immutable(state0);
// the following is illegal as it requires assignment to
// an immutable object
var = Immutable(state1);
// however, the following would work as it constructs a new object
// in place of the old one
new (&var) Immutable(state1);
假设没有重要的析构函数可以运行,这在 C++ 中是合法的还是我应该期待未定义的行为?如果它依赖于标准,我可以期望它工作的最小/最大标准版本是什么?
附录:因为似乎人们在 2019 年仍在阅读这篇文章,所以请注意一下——这种模式实际上在现代(17 后)C++ 中使用std::launder() 是合法可行的。
【问题讨论】:
-
你能澄清一下“区分变量和变量存储的对象”是什么意思吗?因为对象肯定不同于一般的变量(例如不对应于变量的对象,或者通过指针间接)。
-
为什么要重新分配给
var?为什么不把它作为一个指针,可以根据需要设置为Immutable不同实例的地址? -
如果你需要改变它,它不是一成不变的。
-
@PeteBecker 这是不正确的。变量(绑定)的可变性和对象本身的可变性是有区别的。出于安全和效率的考虑,通常希望防止对象的可变性,但仍允许变量本身被反弹到不同的对象。请注意,我不是在改变对象,而是完全丢弃旧对象并绑定新对象。
-
C++ 引用语义是指针或引用。变量是值。以及如何实现不变性很重要。
标签: c++ memory language-lawyer placement-new