【问题标题】:c++ Constructor initializer list with complex assignments具有复杂赋值的 c++ 构造函数初始化列表
【发布时间】:2019-12-23 16:57:26
【问题描述】:

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

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

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

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

/* 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
      {}
};

【问题讨论】:

    标签: c++ constructor default-constructor


    【解决方案1】:

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

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

    相关:

    【讨论】:

    • 对这个解决方案不是 100% 满意,但它绝对是最干净的。
    【解决方案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 运算符,我可以随时初始化对象。由于对象在类范围内,我在析构函数中删除它(在类范围的末尾)

    【讨论】:

      【解决方案3】:

      我会建议另一个更清晰的解决方案,在类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))
          {}
      };
      

      注意这个解决方案使用了隐式定义的move构造函数,所以不要忘记修改你的情况,并检查是否需要根据rule of five显式定义它

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-01-26
        • 1970-01-01
        • 1970-01-01
        • 2011-12-24
        相关资源
        最近更新 更多