Нет, вы не можете инициализировать члены базового класса из списка инициализаторов непосредственно. Это происходит потому, что порядок инициализации протекает таким образом,
С ++ Стандартный n3337 § 12.6.2/10
В не делегировании конструктор, инициализации переходит в следующем порядке:
- Во-первых, и только для конструктора из самого производного класса (1.8) виртуальные базовые классы инициализируются в порядке , они появляются на первом пересечении слева направо влево-вправо направленного ациклического графа базы c lasses, где «left-right-right» - это порядок внешний вид базовых классов в производном классе base-specifier-list.
- Тогда прямые базовые классы инициализируются в порядке декларации, как они появляются в базовом спецификаторе-листе (независимо от порядка MEM-инициализаторы).
- Затем нестатические элементы данных инициализируются в порядке, они были объявлены в определении класса (опять же, независимо от порядка MEM-инициализаторах).
- И наконец, составная инструкция корпуса конструктора выполнена.
[Примечание: заказ декларации уполномочен гарантировать, что субобъекты базы и уничтожены в порядке, обратном порядку . - конец примечание]
Таким образом, вы можете указать конструктор в базовом классе (она может быть защищена) и использовать этот один в списке инициализации производного класса (should be preferred), или вы можете назначить к члену базового класса в производном классе 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;
}
Почему? Я еще не сделал «злого наследственного алмаза». @AndreyT принятый ответ в этом вопросе говорит, чтобы сделать базовый счет. У меня есть ... о. Думаю, мне нужно называть базовый класс ctor, а не член ctor. ОК. –
@WhozCraig: даже если это виртуальная база, она все равно не позволит вам инициализировать * косвенные * члены. Виртуальное наследование может потребовать инициализации косвенных * базис *, но не членов. – AnT
@Steven Lu: В принятом ответе говорится, что 'a :: m_z' может быть инициализирован только из списка инициализаторов конструктора' a'. Он не может быть указан в списке инициализаторов конструктора 'b' (как в вашем коде).Язык этого не позволяет. В этом-то и дело. То есть вам нужно добавить другой параметр в конструктор 'a' специально для' m_z' (как и для 'm_x') и передать начальное значение из' b' через этот конструктор. BTW, в вашем коде выше вы должны обратиться к конструктору 'a' из конструктора' b'. В противном случае он не будет компилироваться, поскольку у вас нет конструктора по умолчанию в 'a'. – AnT