9

假设我想要一个接收一些参数的构造函数,并且使用这些参数我可以计算它的成员变量的值。除了成员变量的值不是来自参数的简单赋值。它们需要创建其他对象并转换值,然后才能用作成员变量的值。

这是塞进初始化列表的方法。也非常低效,因为您无法创建变量并重用它们,因此您必须复制代码(并制作同一对象的多个副本)以适合初始化程序列表中的所有代码。

另一种选择是不使用初始化列表,而是调用默认构造函数,然后用简洁的计算覆盖构造函数中的值。

现在如果类没有默认构造函数怎么办?怎么能巧妙地做到这一点?

/* a class without a default constructor */
class A {
  public:
    B x1
    B x2
    A(B x1_, B x2_) : x1{x1_}, x2{x2_} {};
};

/* a class that contains an A object and needs to initialize it based on some complex logic */
class C {
  public:
    A a;
    C(D d) :
      a{b1,b2} // ultimately I just want to initialize a with two B objects
               // but unfortunatelly they require a lot of work to initialize
               // including instantiating other objects and using tons of methods
      {}
};
4

3 回答 3

6

添加一些静态转换方法怎么样?

class C {
  private:
    static B transform1(D&);
    static B transform2(D&);
  public:
    A a;
    C(D d) :
      a{transform1(d),transform2(d)}
      {}
};

有关的:

于 2013-11-08T04:11:32.147 回答
2

在这种情况下,我会使用指针,这是您示例的修改版本:

//Class A is not modified
/* a class without a default constructor */
class A {
  public:
    B x1
    B x2
    A(B x1_, B x2_) : x1{x1_}, x2{x2_} {};
};



/* a class that contains an A object and needs to initialize it based on some complex logic */
class C {
  public:
    A* a;   // I declare this as a pointer
    C(D d)
      {
          // Perform all the work and create b1,b2
          a = new A(b1, b2);
      }

    ~C()    // Create a destructor for clean-up
    {
          delete a;
    }

};

使用 new 运算符,我可以随时初始化对象。由于对象在类范围内,我在析构函数中删除它(在类范围的末尾)

于 2013-11-08T05:13:03.703 回答
0

我会建议另一个更清晰的解决方案,在类中创建A具有所有复杂构造逻辑的静态方法。

class A {
public:
   B x1
   B x2
   A(B x1_, B x2_) : x1{x1_}, x2{x2_} {};

   static A FromD(D d) {
       B b1, b2;
       /* Some complex logic filling b1 and b2 */
       return A(b1, b2);
   }
};

class C {
public:
    A a;
    C(D d) :
      a(A::FromD(d))
    {}
};

请注意,此解决方案使用隐式定义的移动构造函数,因此不要忘记修改您的情况并检查是否需要根据五规则显式定义它

于 2019-12-23T08:57:26.103 回答