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

Sharpen Your Coding Skills
Programmer Puzzle - Hermit Boxes

Can you program a solution to this puzzle  in which you place 3D boxes on a 2D grid to prevent your opponent being able to make a legal move? Let's hear what the team at International Storm Door  [ ... ]


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 [ ... ]


Python
Programmer Puzzle - Python Swallows A Global

Here's a teaser that poses a practical problem - one that crops up in everyday Python programming. See if you can work out the answer before looking at its solution and the pattern to follow to avoid  [ ... ]


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.