Ah, there it is...
Once the constructor
body is entered, all member variables of the class
have been initialized - by values in the initialization list where available, or by their default constructor otherwise.
That is the reason why you cannot assign new values to const or reference types: They have been initialized, and their very nature forbids reassignment.
As for the claim for efficiency, consider a [tt]string[/tt] member. If you assign it a value within the constructor body, you not only have a call to the string() default constructor, but another one to string.operator=() in the constructor body. A sufficiently stupid C++ compiler / library might actually do
three calls: string(), string( char * ), and string.operator=()...
Meyers writes on this:
Initializing using an initialization list is always legal, never less efficient than an assignment in the constructor body, and often more efficient.
One exception is when you have lots of
native datatypes as members - let's say, two dozen [tt]int[/tt] members. Here, there's no costly "default constructor" to be called; and writing an initialization list for two dozen [tt]int[/tt]s
for every constructor (don't forget the various copy / cast constructors) would be awkard, and error-prone. In this case, write a private (inline) [tt]init()[/tt] function that does the initialization, and call it from each constructor.