Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

c++ Constructor initializer list with complex assignments

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
      {}
};
like image 679
Carneiro Avatar asked Nov 08 '13 03:11

Carneiro


2 Answers

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?
like image 150
leewz Avatar answered Oct 05 '22 23:10

leewz


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)

like image 42
galdin Avatar answered Oct 06 '22 01:10

galdin