Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.

like image 379
gvgramazio Avatar asked Nov 04 '15 11:11

gvgramazio


People also ask

What is initialization list in constructor?

Initializer List is used in initializing the data members of a class. The list of members to be initialized is indicated with constructor as a comma-separated list followed by a colon. Following is an example that uses the initializer list to initialize x and y of Point class.

Why should initializer lists be used rather than assigning member variables values in the constructor body?

Initialization lists allow you to choose which constructor is called and what arguments that constructor receives. If you have a reference or a const field, or if one of the classes used does not have a default constructor, you must use an initialization list.

What is the difference between initialization and assignment of variables?

What is the difference between initialization and assignment? Initialization gives a variable an initial value at the point when it is created. Assignment gives a variable a value at some point after the variable is created.

What are the advantages of initializer list?

The most common benefit of doing this is improved performance. If the expression whatever is the same type as member variable x_, the result of the whatever expression is constructed directly inside x_ — the compiler does not make a separate copy of the object.


1 Answers

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;
};
like image 184
bolov Avatar answered Sep 22 '22 22:09

bolov