Kundan Kumar Kundan Kumar - 2 months ago 9
C++ Question

When should we not use initialization list in the constructor?

Can someone please quote an example code when we should not use initialisation list in the constructor and how that can be overcome with assignment?

I am looking for an example for the below statement


This might happen when your class has two constructors that need to initialize the
this
object's data members in different orders. Or it might happen when two data members are self-referential. Or when a data-member needs a reference to the this object, and you want to avoid a compiler warning about using the this keyword prior to the { that begins the constructor's body (when your particular compiler happens to issue that particular warning). Or when you need to do an if/throw test on a variable (parameter, global, etc.) prior to using that variable to initialize one of your this members.

Answer

Here are some examples:


This might happen when your class has two constructors that need to initialize the this object's data members in different orders.

class Example1 {
 public:
  Example1(std::string decoded, std::string encoded)
      : decoded_(decoded),
        encoded_(encoded) {}
  explicit Example1(std::string encoded)
      : decoded_(),  // Can't use "decoded_(Decode())" since "encoded_" isn't initialised
        encoded_(encoded) {
    decoded_ = Decode();  // Assign here instead of initialising
  }
 private:
  std::string Decode();  // decodes class member "encoded_"
  std::string decoded_, encoded_;
};

In this example, decoded_ will always be initialised before encoded_ since that's the order in which they are declared in the class, even if we swap their order in the initialisation list.


Or when a data-member needs a reference to the this object, and you want to avoid a compiler warning about using the this keyword prior to the { that begins the constructor's body (when your particular compiler happens to issue that particular warning).

class Example2 {
 public:
  Example2() : functor_() {
    functor_ = std::bind(&Example2::Do, this);
  }
 private:
  void Do();
  std::function<void()> functor_;
};

Here, functor_ needs to use this when it is initialised/assigned. If we were to intialise functor_ in the initialisation list, the this pointer would be referring to an object which at that point wasn't fully initialised. That could be safe depending on the particular circumstances, but the foolproof option is to defer setting functor_ until inside the constructor body, by which point this does refer to a fully-initialised object.


Or when you need to do an if/throw test on a variable (parameter, global, etc.) prior to using that variable to initialize one of your this members.

class Example3 {
 public:
  Example3(int force, int acceleration)
      : force_(force),
        acceleration_(acceleration),
        mass_(0) {
    if (acceleration_ == 0)
      throw std::exception("Can't divide by 0");
    mass_ = force_ / acceleration_;
  }
 private:
  int force_, acceleration_, mass_;
};

Hopefully this is self-explanatory.


I'm not sure what is meant by

when two data members are self-referential

so I can't give an example for that I'm afraid.