Spec-Zone.ru › C++

Конструкторы по умолчанию

Конструктор по умолчанию — это конструктор, который можно вызвать без аргументов.

Синтаксис

имя_класса (список_параметров (необязательно)); (1)
имя_класса (список_параметров (необязательно)) тело_функции (2)
имя_класса () = default; (3) (с C++11)
имя_класса (список_параметров (необязательно)) = delete; (4) (с C++11)
имя_класса ::имя_класса (список_параметров (необязательно)) тело_функции (5)
имя_класса ::имя_класса () = default; (6) (с C++11)
имя_класса - класс, для которого объявляется конструктор по умолчанию
список_параметров - список параметров, где все параметры (кроме упаковок параметров)(с C++11) имеют значения по умолчанию
тело_функции - тело функции конструктора по умолчанию

Объяснение

1) Объявление конструктора по умолчанию внутри определения класса.
2-4) Определение конструктора по умолчанию внутри определения класса.
3) Конструктор по умолчанию явным образом задан по умолчанию.
4) Конструктор по умолчанию удалён.
5,6) Определение конструктора по умолчанию вне определения класса (класс должен содержать объявление (1)).
6) Конструктор по умолчанию явным образом задан по умолчанию.

Конструкторы по умолчанию вызываются во время инициализации по умолчанию и значимой инициализации.

Неявный конструктор по умолчанию

Если для типа класса не предоставлено ни одного объявленного пользователем конструктора, компилятор всегда объявляет конструктор по умолчанию как inline public член своего класса.

Если присутствуют некоторые объявленные пользователем конструкторы, пользователь всё же может заставить компилятор автоматически сгенерировать конструктор по умолчанию, который в противном случае был бы неявно объявлен, с ключевым словом default.

(с C++11)

Неявно объявленный (или заданный по умолчанию при первом объявлении) конструктор по умолчанию имеет спецификацию исключений, как описано в спецификации динамических исключений(до C++17) спецификации noexcept(с C++17).

Неявный конструктор по умолчанию

Если конструктор неявно объявлен(до C++11)неявно объявленный или явным образом заданный по умолчанию конструктор по умолчанию не определён как удалённый(с C++11), он определяется (то есть генерируется и компилируется тело функции) компилятором, если odr-используется или необходим для вычисления констант(с C++11), и он имеет тот же эффект, что и конструктор, определённый пользователем, с пустым телом и пустым списком инициализаторов. То есть, он вызывает конструкторы по умолчанию для базовых классов и для нестатических членов этого класса. Типы классов с пустым предоставленным пользователем конструктором могут обрабатываться по-разному, чем те, у которых конструктор по умолчанию определён неявно, во время значимой инициализации.

Если это удовлетворяет требованиям constexpr-конструктора(до C++23)constexpr-функции(с C++23), сгенерированный конструктор является constexpr.

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

(с C++11)

Удалённый конструктор по умолчанию

Неявно объявленный или явным образом заданный по умолчанию(с C++11) конструктор по умолчанию для класса T неопределён(до C++11)определён как удалённый(с C++11), если выполняется любое из следующих условий:

  • T является объединением, и все его члены-варианты имеют тип с квалификатором const (или, возможно, многомерный массив такого типа).
  • T является классом, не являющимся объединением, и все члены любого анонимного объединения имеют тип с квалификатором const (или, возможно, многомерный массив такого типа).
  • T имеет нестатический член данных ссылочного типа без инициализатора по умолчанию(с C++11).
  • T имеет нестатический член данных, не являющийся вариантом, без const-конструктора по умолчанию с квалификатором const (или, возможно, многомерный массив такого типа) без инициализатора члена по умолчанию(с C++11).
  • T имеет подобъект типа класса M (или, возможно, многомерный массив такого типа), такой что
    • M имеет деструктор, который удалён или(с C++11) недоступен из конструктора по умолчанию, или
    • выполняются все следующие условия:
  • Подобект не является нестатическим членом данных с инициализатором по умолчанию.
  • Подобект не является членом-вариантом объединения, где другой нестатический член данных имеет инициализатор по умолчанию.
(с C++11)
  • Резолюция перегрузки при поиске конструктора по умолчанию M
    • не приводит к применимому кандидату, или
    • в случае, когда подобект является членом-вариантом, выбирает нетривиальную функцию.

Если нет определённых пользователем конструкторов и неявно объявленный конструктор по умолчанию не тривиален, пользователь всё же может запретить автоматическое создание компилятором неявно определённого конструктора по умолчанию с помощью ключевого слова delete.

(с C++11)

Тривиальный конструктор по умолчанию

Конструктор по умолчанию для класса T тривиален (т.е. не выполняет никаких действий), если выполняются все следующие условия:

  • Конструктор не предоставлен пользователем (т.е. неявно определён или задан по умолчанию при первом объявлении).
  • T не имеет виртуальных членов функций.
  • T не имеет виртуальных базовых классов.
  • T не имеет нестатических членов с инициализаторами по умолчанию.
(с C++11)
  • Каждый непосредственный базовый класс T имеет тривиальный конструктор по умолчанию.
  • Каждый нестатический член типа класса (или массив такого типа) имеет тривиальный конструктор по умолчанию.

Тривиальный конструктор по умолчанию — это конструктор, который не выполняет никаких действий. Все типы данных, совместимые с языком C (типы POD), тривиально допускают конструкцию по умолчанию.

Допустимый конструктор по умолчанию

Конструктор по умолчанию допустим, если он либо объявлен пользователем, либо является неявно объявленным и определяемым.

(до C++11)

Конструктор по умолчанию допустим, если он не удалён.

(с C++11)
(до C++20)

Конструктор по умолчанию допустим, если

  • он не удалён, и
  • его связанные ограничения, если таковые имеются, удовлетворяются, и
  • ни один конструктор по умолчанию не является более ограниченным, чем он.
(с C++20)

Тривиальность допустимых конструкторов по умолчанию определяет, является ли класс типом явного срока жизни и является ли класс тривиальным типом.

Пример

struct A
{
    int x;
    A(int x = 1): x(x) {} // user-defined default constructor
};
 
struct B : A
{
    // B::B() is implicitly-defined, calls A::A()
};
 
struct C
{
    A a;
    // C::C() is implicitly-defined, calls A::A()
};
 
struct D : A
{
    D(int y) : A(y) {}
    // D::D() is not declared because another constructor exists
};
 
struct E : A
{
    E(int y) : A(y) {}
    E() = default; // explicitly defaulted, calls A::A()
};
 
struct F
{
    int& ref; // reference member
    const int c; // const member
    // F::F() is implicitly defined as deleted
};
 
// user declared copy constructor (either user-provided, deleted or defaulted)
// prevents the implicit generation of a default constructor
 
struct G
{
    G(const G&) {}
    // G::G() is implicitly defined as deleted
};
 
struct H
{
    H(const H&) = delete;
    // H::H() is implicitly defined as deleted
};
 
struct I
{
    I(const I&) = default;
    // I::I() is implicitly defined as deleted
};
 
int main()
{
    A a;
    B b;
    C c;
//  D d; // compile error
    E e;
//  F f; // compile error
//  G g; // compile error
//  H h; // compile error
//  I i; // compile error
}

Отчёты о дефектах

Следующие отчёты о дефектах, изменяющие поведение, были применены ретроактивно к ранее опубликованным стандартам C++.

DR Применено к Поведение, как опубликовано Правильное поведение
CWG 1353 C++98 условия, при которых неявно объявленные конструкторы по умолчанию
были неопределёнными, не учитывали многомерные типы массивов
учитывать эти типы
CWG 2084 C++11 инициализаторы членов по умолчанию не оказывали влияния на то,
удаляется ли неявно объявленный конструктор по умолчанию для объединения
они препятствуют удалению неявно объявленного
конструктора по умолчанию

См. также

  • конструктор
  • инициализация
    • инициализация агрегата
    • инициализация констант
    • инициализация копированием
    • инициализация по умолчанию
    • прямая инициализация
    • инициализация списком
    • инициализация ссылками
    • инициализация значением
    • нулевая инициализация
  • new

© cppreference.com
Licensed under the Creative Commons Attribution-ShareAlike Unported License v3.0.
https://en.cppreference.com/w/cpp/language/default_constructor

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API