The point is that class members are constructed before the constructor body is entered.
Code:
class A
{
int a , b;
public:
A(int x, int y)
//x and y are constructed here
{
a = x; b = y; //just assignments
}
};
Now, the above works without an initializer list.
Let's suppose however, that we have a class that contains an instance of another class, which does not have a default constructor (i.e cannot be constructed without arguments).
What happens is that the member object (A) needs to be created before entering the constructor body of ContainsA, but the compiler cannot call the constructor of this object, if you don't give it the arguments. That you can only do in the initializer list.
Try out the next program. Comment out the initializer list of ContainsA, and see if you can still somehow make this code compile without modifying A.
Code:
#include <iostream>
class A
{
int a, b;
public:
A(int x, int y)
{
a = x;
b = y;
}
void print() const
{
std::cout << a << ", " << b;
}
};
class ContainsA
{
A a;
int c;
public:
ContainsA(int x, int y, int z)
//This wouldn't work without an initializer, because here member "a" has to be constructed
//but no default constructor has been provided.
//Hence:
: a(x, y) //Try without this and see that it doesn't compile
{
c = z; //could be done in initializer too
}
void print() const
{
a.print();
std::cout << ", " << c << '\n';
}
};
int main()
{
ContainsA test(1, 2, 3);
test.print();
std::cin.get();
}
Another situation where you absolutely need to use the initialization list, is if the class contains const members. Those can only be initialized where they are created, and that happens before the opening brace.
In general: use initializer lists whenever you can. They are more efficient, very readable and easy to type