c++ Constructor initializer list with complex assignments

久未见 提交于 2020-01-20 08:06:33

问题


Suppose I want to have a constructor that receives some parameters, and with these parameters I can calculate the values for it's member variables. Except that the values for the member variables are not simple assignments from the parameters. They require creation of other objects and transformation of the values before they can be used as values for the member variables.

This is way to much to cram into an initializer list. Also very inefficient since you can't create variables and reuse them so you will have to copy code (and make several copies of the same object) to fit all the code in the initializer list.

The other option is not to use the initializer list and let the default constructor be called then you overwrite the values inside the constructor with neat calculations.

Now what if the class does not have a default constructor? How can one do this neatly?

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

回答1:


How about adding some static transformation methods?

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

Related:

  • Is there any problem of calling functions in the initialization list?
  • Is it ok to call a function in constructor initializer list?
  • can member functions be used to initialize member variables in an initialization list?



回答2:


I would use pointers in this case, Here's the modified version of your example:

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

};

Using the new operator I can initialize the object whenever I want. And since the object is in the class scope, I delete it in the destructor (at the end of the class scope)




回答3:


I would suggest another more clear solution, create static method in class A with all complex logic of constructing.

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))
    {}
};

Note that this solution uses implicitly defined move constructor, so don't forget to revise your situation and check if you need to define it explicitly according to rule of five



来源:https://stackoverflow.com/questions/19851348/c-constructor-initializer-list-with-complex-assignments

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!