Этот фрагмент кода
class A {
public:
int x;
};
class B : public A {
public:
B() : x(0) {} // error
};
является неправильным, поскольку в соответствии со стандартом C ++ (12.6.2 Инициализация баз и членов)
2 В идентификаторе mem-initializer-id начальный неквалифицированный идентификатор ищется в области видимости класса конструктора и, если не найден в этой области видимости, он ищется в области видимости, содержащей определение конструктора. [Примечание: если класс конструктора содержит член с тем же именем, что и у прямого или виртуального базового класса класса, mem-initializer-id, именующий элемент или базовый класс и состоящий из одного идентификатора, ссылается на член класса. Mem-initializer-id для скрытого базового класса может быть указан с использованием квалифицированного имени. - примечание конца] Если только mem-initializer-id не присваивает имя классу конструктора, элементу данных non-stati c класса конструктора или прямой или виртуальной базе этого класса, mem-initializer является недействительным Formed.
Вместо этого вы можете написать
class A {
public:
int x;
};
class B : public A {
public:
B() : A{ 0 } {}
};
, где в mem-initializer-list используется прямой идентификатор базового класса.
Обратите внимание на что вместо скобок используются скобки A{ 0 }
, поскольку class A
является агрегатом.
В этом фрагменте кода
class A {
public:
int x;
};
class B : public A {
public:
B() { x = 0; } // ok
};
Элемент данных x
отсутствует в mem-initializer-list и назначается в теле конструктора после инициализации по умолчанию. То есть в теле конструктора используется оператор присваивания для уже созданного объекта.