I'm having a hard time finding hits on google for this.
struct a {
float m_x;
float m_z;
public:
a(float x): m_x(x) {}
};
class b : public a {
b(float z): m_z(z) {}
};
On clang 3.2:
error: member initializer 'm_z' does not name a non-static data member or base class
b(float z): m_z(z) {}
No you cannot initialize base class members from initializer list directly. This is because order of initialization proceeds in this way
C++ Standard n3337 § 12.6.2/10
In a non-delegating constructor, initialization proceeds in the following order:
— First, and only for the constructor of the most derived class (1.8), virtual base classes are initialized in the order they appear on a depth-first left-to-right traversal of the directed acyclic graph of base classes, where “left-to-right” is the order of appearance of the base classes in the derived class base-specifier-list.
— Then, direct base classes are initialized in declaration order as they appear in the base-specifier-list (regardless of the order of the mem-initializers).
— Then, non-static data members are initialized in the order they were declared in the class definition (again regardless of the order of the mem-initializers).
— Finally, the compound-statement of the constructor body is executed.
[ Note: The declaration order is mandated to ensure that base and member subobjects are destroyed in the reverse order of initialization. — end note ]
So you can specify a constructor in a base class (it can be protected) and use that one in initialization list of derived class (should be preferred) or you can assign to a base class member in derived class ctor body (different behaviour, different effect and also less efficient - you are assigning to default initialized (already has value) member).
In the former case you might write it this way:
struct A {
float m_x;
float m_z;
A(){}
protected:
A(float x): m_x(x) {}
};
class B : public A {
public:
B(float z) : A(z) {}
// alternatively
// B(float z) {
// m_x = z;
// }
};
int main(){
B b(1);
return 0;
}