Monday, March 31, 2008

Constructor Initialization List

Look at this piece of code, is it strange to you?
class A
{
private:
size_t i_;

public:
A( size_t i ): i_( i ) { };
};
Does the constructor look strange? In fact, it has no problem at all. It's different to the following constructor:
A( size_t i )
{
i_ = i;
}
Because in the first case the value of i_ will be set before entering constructor, while in the second case the value of i_ will be undetermined when the constructor is created.
You should always use a constructor list if possible as it is much more efficient than constructing ( ie default constructor) and then assigning. One important thing to remember is that the elements in your constructor list are initialized in the order that they were declared, NOT the order you write them, so:
class A
{
private:
int i_;
int j_;

public:
A( int i ): j_( i ), i_( 2 * j_ ) { }
};
It is undefined behaviour since i_ is constructed before j_, so at the point the program executes 2 * j_, j_ does not exist. However,
class A
{
int i_;
int j_;

public:
A( int i ): j_( 2 * i_ ), i_( i ) { }
};
It is absolutely fine, but it is confusing for a human to read, because it looks like it is being done in the wrong order. Because of this, when writing constructors, an excellent habit to get in to is to write the variables in the same order as you have declared them. Most of the time it makes no difference, but every now and again it will save you from creating a rather subtle bug.

No comments: