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

PHP
The Missing PHP Global

A global variable is a global variable and that's all there is to it. But if you write PHP code to be used by other people, you might want to consider that this isn't always the case. Can you see wher [ ... ]


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
Jigsaw Puzzles and The MacMahon Squares

Another puzzle featuring Joe Celko's characterful pair, Melvin Frammis, an experienced developer at International Storm Door & Software, and his junior programmer sidekick, Bugsy Cottman. This cla [ ... ]


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.