Инициализация значения для классов с исключительно унаследованными конструкторами

В соответствии с cppreference несоединимые классы без каких-либо предоставленных пользователем конструкторов будут инициализироваться нулями перед созданием:

Если T является типом класса без объединения без каких-либо предоставленных пользователем конструкторов, то объект инициализируется нулями, а затем вызывается неявно объявленный конструктор по умолчанию (если это не тривиально)

Я не уверен, что должно произойти, когда используются унаследованные конструкторы C++11, поскольку в кавычке явно упоминается неявно объявленный конструктор по умолчанию.

Учитывая следующий пример:

#include <iostream>

struct A {
    int a;
    A() {}
    A(int i): a(i) {}
};

struct B: public A {
    using A::A;
};

int main() {
    B b { 5 };
    B* p = new (&b) B{ };
    std::cout << b.a << std::endl;
}

Каков правильный вывод, 0 или 5? Должен ли тип класса, исключительно предоставляющий унаследованные конструкторы, инициализироваться нулями до инициализации значения (B{ })?

1 ответ

Решение

Правильный ответ 0 потому что конструктор по умолчанию для B неявно объявлено.

Обратите внимание, что конструкторы копирования и перемещения по умолчанию не наследуются; цитирование из §12.9/3 [class.inhctor]

Для каждого нешаблонного конструктора в наборе-кандидате унаследованных конструкторов, отличных от конструктора, не имеющего параметров, или конструктора копирования / перемещения, имеющего один параметр, конструктор неявно объявляется с теми же характеристиками конструктора, если только не существует декларируемый пользователем конструктор с та же самая подпись в полном классе, где появляется объявление using, или конструктор будет конструктором по умолчанию, копировать или перемещать для этого класса.


Ваш пример похож на приведенный в N3797, §12.9 / 6 (отредактировано для краткости)

struct B2 {
  B2(int = 13, int = 42);
};

struct D2 : B2 {
  using B2::B2;
};

Набор кандидатов унаследованных конструкторов в D2 за B2 является
- B2(const B2&)
- B2(B2&&)
- B2(int = 13, int = 42)
- B2(int = 13)
- B2()

Набор конструкторов присутствует в D2 является
- D2(), неявно объявленный конструктор по умолчанию, не наследуется
- D2(const D2&), неявно объявленный конструктор копии, не наследуется
- D2(D2&&), неявно объявленный конструктор перемещения, не наследуется
- D2(int, int), неявно объявленный наследующий конструктор
- D2(int), неявно объявленный наследующий конструктор

В вашем случае набор кандидатов унаследованных конструкторов в B за A являются

A()
A(int)
A(const& A)
A(A&&)

и конструкторы, присутствующие в B являются

B() implicitly declared, not inherited
B(int) implicitly declared, inherited
B(const& B) implicitly declared, not inherited
B(B&&) implicitly declared, not inherited
Другие вопросы по тегам