Пространства имён
Варианты
Действия

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

Материал из cppreference.com
< cpp‎ | language
 
 
 
 

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

Содержание

[править] Синтаксис

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

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

(начиная с C++11)

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

Конструктор по умолчанию для класса 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) {} // определяемый пользователем конструктор по умолчанию
};
 
struct B: A
{
    // B::B() iопределяется неявно, вызывает A::A()
};
 
struct C
{
    A a;
    // C::C() определяется неявно, вызывает A::A()
};
 
struct D: A
{
    D(int y): A(y) {}
    // D::D() не объявлен, потому что существует другой конструктор
};
 
struct E: A
{
    E(int y): A(y) {}
    E() = default; // объявлен явно по умолчанию, вызывает A::A()
};
 
struct F
{
    int& ref; // элемент ссылка
    const int c; // константный элемент
    // F::F() неявно определяется как удалённый
};
 
// объявленный пользователем конструктор копирования (предоставленный пользователем,
// удалённый или заданный по умолчанию) предотвращает неявное создание конструктора
// по умолчанию
 
struct G
{
    G(const G&) {}
    // G::G() неявно определяется как удалённый
};
 
struct H
{
    H(const H&) = delete;
    // H::H() неявно определяется как удалённый
};
 
struct I
{
    I(const I&) = default;
    // I::I() неявно определяется как удалённый
};
 
int main()
{
    A a;
    B b;
    C c;
//  D d; // ошибка компиляции
    E e;
//  F f; // ошибка компиляции
//  G g; // ошибка компиляции
//  H h; // ошибка компиляции
//  I i; // ошибка компиляции
}

[править] Отчёты о дефектах

Следующие изменения поведения были применены с обратной силой к ранее опубликованным стандартам C++:

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

[править] Смотрите также