Explain this code

Can someone explain this code, I understand that it is a constructor function and that the value of int val is assigned to x but i dont understand the syntax involved.
1
2
3
4
MyClass(int val) : x(val) {}

/* How i would've written it */
MyClass(int val){x=val}
What you have between the argument list and the function body is called the initializer list. This is where there is a key difference between the first constructor and how you would have written it.

1
2
3
4
5
6
7
8
MyClass(int val)
    : x(val)  // x is not "assigned" val, but rather x is "initialized" with val
{}

MyClass(int val)
{ //By this point, x has been initialized with a junk value
    x=val; //Now x is "assigned" val
}


And here is analogous code following the same order:
1
2
3
4
5
6
//Analogy to the first constructor
int x(5); //x is initialized with 5

//Analogy to the second constructor
int x; //x has been initialized with some junk value
x = 5; //Now x is assigned 5 


When is this distinction important?

Consider two possibilities:

1) A member variable is constant. Therefore, it must be initialized as you cannot assign anything to it.
1
2
3
4
5
6
7
8
9
struct MyClass{
    const int x;

    MyClass(int val)
        : x(val) //Correct. x is intialized
    {
        //x = val;   // Error. Const variable may not be modified.
    }
};


2) A member variable is an object of a class that has no default constructor (a constructor that takes no arguments). This also forces the variable to be initialized.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
struct MemberClass{
    int y;
    MemberClass(int val) //<-- This is the only constructor available (ignoring copy and move)
                                 // So MemberClass::MemberClass() does not exist
        : y(val)
    {}
};

struct MyClass{
    MemberClass mem;
    int x;
/*
    MyClass(int val)
    { // Error. MemberClass has no constructor MemberClass::MemberClass()
        mem = MemberClass(val);
    }
*/
    MyClass(int val)
        : mem(val) //Correct. This calls mem's constructor.
        , x(val >> 1)
    {}
};


Also remember that in the initializer list, you should initialize the variables in the order they were declared, like I did in the above example.



On a side note:
For C++11, you can also call another constructor from the initializer list.
1
2
3
4
5
6
7
8
9
10
11
struct MyClass{
    const int x;

    MyClass()
         : MyClass(0) //Calls the second constructor that takes an int argument
    {}

    MyClass(int val)
        : x(val)
    {}
};
Thanks I didn't know about the initializer list.
Topic archived. No new replies allowed.