Spec-Zone.ru › C++

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

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

Синтаксис

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

Пояснение

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

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

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

Если для типа класса не объявлен пользовательский конструктор или шаблон конструктора, компилятор неявно объявляет конструктор по умолчанию как член своего класса со спецификаторами inlinepublic.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Подходящий конструктор по умолчанию

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

(до C++11)

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

(начиная с C++11)
(до C++20)

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

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

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

Примечания

Макрос проверки поддержки возможностей Значение Стандарт Возможность
__cpp_trivial_union 202502L (C++26) Смягчение требований к тривиальности специальных функций-членов объединений

Пример

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++11 условия, при которых неявно объявленные конструкторы по умолчанию
определяются как удалённые, не учитывали многомерные массивы
учитывать такие типы
CWG 2084 C++11 инициализаторы членов по умолчанию не влияли на то, будет ли
заданный по умолчанию конструктор по умолчанию объединения удалён
они предотвращают удаление заданного по умолчанию
конструктора по умолчанию
CWG 2595 C++20 конструктор по умолчанию не считался подходящим, если существует
другой конструктор по умолчанию, который более ограничен,
но его связанные ограничения не выполнены
в этом случае он может быть подходящим
CWG 2871 C++98 конструктор по умолчанию объявлялся неявно,
даже если был объявлен пользователем шаблон конструктора
в этом случае не объявляется
неявно

См. также

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

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

Spec-Zone.ru

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