最好用正确的值实例化对象,然后推送到向量,或实例化,推送到向量然后设置正确的值?

时间:2014-11-28 21:02:36

标签: c++ algorithm oop vector

说我有一个这样的课程:

class Foo{
    Foo* otherFooObj;
    Foo* otherFooObj2;
.....
};

更好的是:

一个。

  1. 使用函数
  2. 获取成员变量的正确值(otherFooObjotherFooObj2的地址等)
  3. 使用正确的值实例化(构造)Foo对象。
  4. 将对象推向矢量。
    1. 使用虚拟值实例化Foo对象(otherFooObjotherFooObj2的虚拟地址)
    2. 将对象推向矢量。
    3. 使用函数将Foo对象的成员变量设置为正确的值,一旦它位于向量内部。
    4. 下进行。

      1. 使用虚拟值
      2. 实例化Foo对象
      3. 使用函数获取正确的值并将Foo的成员变量设置为这些值
      4. 将对象推向矢量。
      5. 现在,我认为这些设计模式之间没有太大区别,并且我遵循哪个流程并不重要。但我想对此有更多的意见,并想知道是否还有其他因素我忽略了,我应该考虑(我觉得有,也许有指针等)。

2 个答案:

答案 0 :(得分:2)

这个问题有点过于笼统,无法妥善回答。一个好的设计目标是只在有效状态下拥有对象,通过设计中的某些有效定义。替代方案是不能相信一个对象事先处于有效状态,这会使你的生活变得复杂并导致你错误地出现一个半生不熟的对象。

从这个角度来看,我会为成员创建值,并调用一个构造函数,将对象从不存在的状态移动到该有效状态。

在您的情况下,您似乎正在构建一个自引用数据结构:图形,树或类似的东西。如果是这种情况,可能是Foo将两个成员设置为nullptr有意义并且您可以考虑替代方案,但我仍然会提供一个构造函数,使您能够设置对象到一个完整的状态:

class Foo {
   Foo *a, *b;
public:
   Foo() : a(), b() {} // initialize both to nullptr, assuming this is a *valid* state
   Foo(Foo *a, Foo *b) : a(a), b(b) {}
...
};

回到最初的问题,我会选择为成员创建值并将 emplace 创建到向量中:

Foo *a = f();
Foo *b = f();
vector.emplace_back(a, b);

答案 1 :(得分:1)

避免生成无效状态。如果您没有设置成员指针,那么至少您必须将它们设置为nullptr。如果可能的话,尽快生成一个有用且有效的状态(除非这是昂贵的,否则你可能想要使用延迟初始化,但仍然是一个有效但不完整的初始状态)。因此,如果您可以获得成员的最终正确值,请立即设置它们。

如果这些指针拥有任何内存(从新分配的内存初始化),那么你必须非常小心。在这种情况下,您实际上应该使用std::unique_ptr<>并移动您的对象,甚至可以通过vector::emplace_back()直接在其向量位置构建。

另外,如果您事先知道了对象的总数,那么在将对象放入向量之前,您可能需要vector::reserve()足够的空间。