【发布时间】:2018-06-14 10:12:02
【问题描述】:
我有一个类对象的实例,我想将其重置为其原始状态。 它有一个经过良好测试的构造函数。 通常我会用像
这样的代码来做到这一点myObject = MyObject{};
但临时对象太大而无法放入堆栈。
我的选择是
1) 在堆上创建一个默认的临时对象
auto* tempObject = make_unique<MyObject>();
myObject = *tempObject;
2) 使用placement new 就地销毁和重建
myObject.~MyObject();
new( &myObject) MyObject();
3) 将构造函数代码重构为一个单独的重置函数,该函数可从构造函数和其他任何地方调用。
MyObject::MyObject()
{
reset();
}
//and
myObject.reset();
我特别不喜欢任何选项:1) 在项目中在堆上分配,试图避免不必要的分配 2) 脆弱且有异味 Can I use placement new(this) in operator=? 3) 我很懒,想避免重构,如果我可以。
我想我真正要问的是还有其他我错过的方法吗?理想情况下是否有某种可以应用的优化,这意味着编译器可以省略在堆栈上创建临时项并允许我使用我的原始代码?
【问题讨论】:
-
项目中堆分配的限制是什么?如果你可以控制时间和多少,它仍然是一个问题吗?您可以为该实例分配一次,并为每次后续重置使用新位置。还是我错过了什么?
-
@Baldrick (2) 的问题是,在抛出构造函数的情况下,您最终可能会得到未定义的对象状态。
-
我认为 (1) 和 (2) 将涉及编写某种
reset函数以及为了封装。专用的reset函数具有明确的目的,并且很可能是非抛出的(与初始构造函数调用不同)。所以(3)似乎是一个显而易见的选择。 -
@VTT 我同意。有时你只需要做硬码。对我来说,唯一可行的选择是准确评估选项 1 的成本并决定是否更可口,