A problem of order - constructor initialization
Written by Alex Armstrong   
Article Index
A problem of order - constructor initialization
Solution

 

Solution

The key to finding the problem is to simply check the value of a and b in an instance of the class. The result for example obtained on one run was

 a=3795240 b=20   

This is clearly not right and the first value and the fact it was different each time the program is run suggests that a is being initialized with random crud.

The reason is that the background information provided at the start of this puzzle left out one important point that is often overlooked. The order that initializations are carried out isn't determined by the order that they are written in the initialization list but by the order in which the variables are declared. This is simple enough but when you look at:

MyClass(int value) : b(value*2),a(b)

you can't help but read the instructions in order and you mind just believes that this is the default flow of control. That is the list is equivalent to:

b=value*2;
a=b;

However what the compiler does is read the variable declarations and then apply the initialization you specified in the list. So in fact the declarations are re-written as:

int a=b;
int b=value*2;

And now you can see quite clearly where the undefined value comes from. Of course if you actually wrote the above you would get a compiler error that b wasn't defined but you usually don't get that error from an initialization list that implies the same thing.

Pattern

The best way of avoiding this sort of error is not to use constructor initialization lists at all but this is slightly restrictive. Initialization lists are more efficient than writing code into the body of the constructor in the case of object members. The reason is that putting assignments in to the body of the constructor first initializes everything to default values, using their default constructors and then applies the assignment initializers which creates a temporary object and then uses the object's assignment operator. For intrinsic types such as int there is no real difference between the two methods.

Also you cannot initialize const or reference members within the constructor bodies but you can in an initializer list.

A better rule might be not to reference variables being initialized as values of other variables in the list but once again there are time when it seems natural to do so. For example, if you initialize an object and then want to initialize another variable to reference some member of the first object. For example suppose we have:

class MyClass2
{
public:
int x;
MyClass2():x(3)
{
}
};

And then we use this in other class:

class MyClass
{
private:
MyClass2 myObj2;
int a;
public:
MyClass():a(myObj2.x)
{
}
};

This works fine and a is initialized to whatever myObj2.x is initialized to, i.e. 3 in this case. Now consider:

class MyClass
{
private:
int a;
MyClass2 myObj2;
public:
MyClass():a(myObj2.x)
{
}
};

This doesn't work because myObj2 isn't constructed at the point that the attempt is made to set a to myObj2.x.

Sometimes it just seems safer to always initialize in the constructor.

It is certainly worth remembering that the order of initialization is always the same as the order of declaration.


Banner

More Puzzles

C#
Value Or Reference? A C# Puzzle

The difference between a value and a reference type is very clear to most C# programmers, but it can be a shock when a simple piece of code that seems to do exactly what you want has a surprise in sto [ ... ]


Javascript
Impossible Equalities - a JavaScript puzzle

It is almost folklore that the JavaScript equality operator == is evil and you should always use the strict equality operator === but sometimes it just makes things easier to get JavaScript to do all  [ ... ]


Sharpen Your Coding Skills
Towers Of Hanoi Mutants

Towers of Hanoi is a classic puzzle and is often used to illustrate the idea of recursion. Here Melvin Frammis challenges you to attempt to find solutions to some variations - but first he explains th [ ... ]


Other Articles

<ASIN:0132673266>

<ASIN:059600298X>

<ASIN:0321334876>

<ASIN:156592116X>



 
 

   
RSS feed of all content
I Programmer - full contents
Copyright © 2014 i-programmer.info. All Rights Reserved.
Joomla! is Free Software released under the GNU/GPL License.