Вопрос:
Мне сложно найти хиты в Google для этого.
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) {} };
На 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) {} Ответ №1
Нет, вы не можете инициализировать членов базового класса непосредственно из списка инициализаторов. Это потому, что порядок инициализации продолжается таким образом
С++ Стандарт n3337 § 12.6.2/10
В конструкторе без делегирования инициализация продолжается в в следующем порядке:
– Во-первых, и только для конструктора самого производный класс (1.8), виртуальные базовые классы инициализируются в порядке они появляются на первом переходе слева направо направо ациклический граф базовых классов, где “слева направо” – это порядок появление базовых классов в производном классе базовый спецификатор-лист.
– Затем прямые базовые классы инициализируются в порядок декларации, поскольку они отображаются в списке-спецификаторе базы (независимо от порядка mem-инициализаторов).
– Затем нестатический элементы данных инициализируются в том порядке, в котором они были объявлены в класса (опять же, независимо от порядка MEM-инициализаторы).
– Наконец, составная формулировка тело конструктора выполнено.
[Примечание: заказ на декларацию уполномочен обеспечивать, чтобы база и член-подобъекты уничтожаются в обратном порядке инициализация. – конечная нота]
Таким образом, вы можете указать конструктор в базовом классе (его можно защитить) и использовать его в списке инициализации производного класса (предпочтительнее), или вы может назначать член базового класса в производном классе ctor body (другое поведение, другой эффект, а также менее эффективно – вы назначаете члену инициализированного по умолчанию (уже имеющего значение)).
В первом случае вы можете написать так:
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; }