Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/ant/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 在c+;中重置大型对象实例的最佳方法是什么+;_C++_C++14 - Fatal编程技术网

C++ 在c+;中重置大型对象实例的最佳方法是什么+;

C++ 在c+;中重置大型对象实例的最佳方法是什么+;,c++,c++14,C++,C++14,我有一个类对象的实例,我想将其重置为原始状态。 它有一个经过良好测试的构造函数。 通常情况下,我会使用类似 myObject = MyObject{}; 但是临时对象太大,无法放在堆栈上 我的选择是 1) 在堆上创建默认的临时对象 auto* tempObject = make_unique<MyObject>(); myObject = *tempObject; 3) 将构造函数代码重构为一个单独的重置函数,该函数从构造函数和其他任何地方调用 MyObject::MyObjec

我有一个类对象的实例,我想将其重置为原始状态。 它有一个经过良好测试的构造函数。 通常情况下,我会使用类似

myObject = MyObject{};
但是临时对象太大,无法放在堆栈上

我的选择是

1) 在堆上创建默认的临时对象

auto* tempObject = make_unique<MyObject>();
myObject = *tempObject;
3) 将构造函数代码重构为一个单独的重置函数,该函数从构造函数和其他任何地方调用

MyObject::MyObject()
{
   reset();
}
//and
myObject.reset();
我特别不喜欢任何选项:1)在试图避免不必要的分配的项目中,在堆上进行分配2)很脆弱,很难闻3)我很懒,如果可以的话,我希望避免重构


我想我真正想问的是,还有其他我错过的方式吗?理想情况下,是否存在某种可以应用的优化,这意味着编译器可以避免在堆栈上创建临时项,并允许我使用原始代码?

最好的-始终是基于意见的解决方案

在通常的实践中,如果您使用OOP并希望重置对象,请编写重置函数,该函数将以您希望的方式完全执行您希望执行的操作

您有基类,因此您可以提供相同的模式,而不会破坏封装或生成脆弱的、误导性的解决方案


p、 s.RAII vs zombie

标准容器可能是一个解决方案:

std::vector<MyObject> v(1);    // require a capacity of 1

v.emplace_back();              // ok v[0] is now a ref to a heap constructed object

v.pop_back();                  // destroys the object
v.emplace_back();              // and rebuilds it normally without any (de-)allocation
标准向量v(1);//需要1的容量 v、 放置_back();//ok v[0]现在是对堆构造对象的引用 v、 弹出_back();//破坏物体 v、 放置_back();//并在不进行任何(取消)分配的情况下正常重建 但我认为正确的解决方案是增加堆栈大小,这仍然是一个难题。所有体面的编译器都有这样的选项


无论如何,重置方法也可以是一个好的、干净的解决方案,只要它从功能的角度来看是有意义的(对象被设计为可重置的)。如果不是,这又是一个黑客行为。

项目中堆上的分配有什么限制?如果你能控制时间和数量,这还会是个问题吗?您可以为该实例分配一次,并在每次后续重置时使用“新放置”。还是我遗漏了什么?@Baldrick(2)的问题是,在抛出构造函数的情况下,您可能会得到未定义的对象状态。我认为(1)和(2)还需要编写某种类型的
reset
函数,以便进行封装。专用的
reset
函数有明确的用途,并且可能是非抛出的(与初始构造函数调用不同)。所以(3)似乎是一个明显的选择。@VTT我同意。有时候你只需要做硬码。对我来说,唯一另一个可行的选择是准确评估期权1的成本,并决定是否更合适,有一件事要考虑的是,为什么要进行重置。如果这是一个热对象,并且您希望节省分配成本,那么您不必编写重置函数。您还可以编写一个初始化,这种方法的优点是您没有无效的对象。@Alex,lazy inits导致zombie objects=)这取决于您如何正确地执行它?如果您在构造函数和init中请求所有内容,那么您可以重用一个对象,而不必调用“reset”,这会导致僵尸对象。
std::vector<MyObject> v(1);    // require a capacity of 1

v.emplace_back();              // ok v[0] is now a ref to a heap constructed object

v.pop_back();                  // destroys the object
v.emplace_back();              // and rebuilds it normally without any (de-)allocation