Search code examples
c++classconstructorconstantsinitializer-list

What is the difference between using initialization lists to initialize fields and initialize them inside the constructor?


On some tutorials (e.g. http://www.tutorialspoint.com/cplusplus/cpp_constructor_destructor.htm) I read that the following two codes are equivalent.

First code:

class MyClass1{
    public:
        int a;
        int b;
        MyClass1(int a, int b) : a(a), b(b) {};
};

Second code:

class MyClass2{
    public:
        int a;
        int b;
        MyClass2(int, int);
};

MyClass2::MyClass2(int a, int b){
    this->a = a;
    this->b = b;
}

In fact, they give me the same results. But, if I use const members I'm not able to compile the code anymore.

class MyClass1{
    public:
        const int a;
        const int b;
        MyClass1(int a, int b) : a(a), b(b) {};
};

class MyClass2{
    public:
        const int a;
        const int b;
        MyClass2(int, int);
};

MyClass2::MyClass2(int a, int b){
    this->a = a;
    this->b = b;
}

In fact the first class give me no error but in the second class there is an assignment of read-only member. So, these are the questions:

What is the real difference among the two methods of initialization?

Is using the initialization lists the only method to initialize const members of a class?

Note: I read online the use of delegating constructors to avoid this problem but it's not clear for me their use and what they really do.


Solution

  • A simple way of looking at it is to make connections with local variables:

    1. Using initializer lists is equivalent to this view of local variables:

      int a = 1;
      int b = 2;
      
    2. The second form, assigning them inside constructor is equivalent to this:

      int a;
      int b;
      
      a = 1;
      b = 2;
      

    You can see how this can be a problem with const or with objects that don't have a default constructor:

    Const members

    1. Ok:

      const int a = 1;
      const int b = 2;
      
    2. Not ok:

      const int a;
      const int b;
      a = 1;
      b = 2;
      

    Types with deleted or not accessible default constructor

    e.g.:

    class X {
    public:
       X() = delete; // default constructor deleted
       X(int){};     // constructor with an int parameter
    };
    
    1. Ok:

      X x(1);
      
    2. Not ok:

      X x;
      x = X(1);
      

    3rd option: In-class member initializers (since c++11)

    class A {
    public:
       const int a = 10;
    };