Using member functions in a constructor initializer
I've come across initializer lists a few times and I've never been able to explain it well. Can someone explain exactly why the following fails (I don't have a compiler to catch typos, so bear with me):
class Foo
{
public:
Foo( int i ) : m_i( i ) {} //works with no problem
int getInt() {return m_i;}
~Foo() {}
private:
int m_i;
};
class Bar
{
public:
Bar() :
m_foo( 5 ), //this is ok
m_myInt( m_foo.getInt() ) //runtime error, seg 11
{}
~Bar() {}
private:
Foo m_foo;
int m_myInt;
};
I get seg errors when trying to call member functions initialized above the initializer list. I seem to remember that this is a known issue (or perhaps one way or another by design), but I've never seen it well described. The attached example is superimposed on plain old data types, but replace Bar::m_myInt
with another object that lacks a default constructor (empty) and the problem is more real. Can anyone enlighten me?
a source to share
The initialization order is independent of the order of the items in the initialization list. The actual order is the order of the members in the class definition. That is, your example m_foo
will initialize to m_myInt
not because of the initialization list, but because the element appears first in the class.
The concrete example you posted should compile and run without issue.
a source to share
Data members are initialized in the order specified in the class declaration (order in private:
in your example). The order specified in the initializer list is not precluded from the build order.
So, in your example, reordering such data items could result in undefined behavior:
private:
int m_myInt;
Foo m_foo;
Is it possible that the order of the data items was really different from what you showed?
a source to share