You can safely call an inherited member function from the initialization list provided that nothing of what that function does depends on how the member data up to that level of inheritance have been initialized. And, since size() doesn't rely on any member data and all what it does is just returning a literal
int size()
{ return 5; }
your code would work with any compiler. So there is even no need to have base_size() in the initialization list
derived() : base_size(), base_implement(size())
in this case.
However, switching to a more realistic example, where base_size has a constructor that initializes an instance variable (i.e. member data), it would make more sense having base_size() in the initialization list:
class base_size
{
public:
base_size ()
{ _size = 5; } // initialization
int size()
{ return _size; }
private:
int _size; // instance variable
};
class base_implement
{
public:
base_implement(int s) : _vec(s)
{
cout << "size : " << _vec.size() << endl;
}
private:
vector<float> _vec;
};
class derived :
public base_implement,
public base_size
{
public:
derived() : base_size(), base_implement(size())
{
// crash
}
};
And, with this specific example, the program would crash because vector wouldn't receive a valid value to allocate its size. And the the reason would be the order of base classes you have in the so-called base-specifier-list:
public base_implement,
public base_size
Referring to an authority, this is what is stated by the standard in section 12.6.2, "Initializing bases and members"
Initialization
answered 2012-07-15T15:07:12.720