Подтвердить что ты не робот

Member инициализатор не называет нестатический элемент данных или базовый класс

Мне сложно найти хиты в 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) {}
4b9b3361

Ответ 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;
}