Конструкторы по умолчанию
Конструктор по умолчанию — это конструктор, который можно вызвать без аргументов.
Синтаксис
имя_класса (список_параметров (необязательно)); | (1) | |
имя_класса (список_параметров (необязательно)) тело_функции | (2) | |
имя_класса () = default; | (3) | (с C++11) |
имя_класса (список_параметров (необязательно)) = delete; | (4) | (с C++11) |
имя_класса ::имя_класса (список_параметров (необязательно)) тело_функции | (5) | |
имя_класса ::имя_класса () = default; | (6) | (с C++11) |
| имя_класса | - | класс, для которого объявляется конструктор по умолчанию |
| список_параметров | - | список параметров, где все параметры (кроме упаковок параметров)(с C++11) имеют значения по умолчанию |
| тело_функции | - | тело функции конструктора по умолчанию |
Объяснение
Конструкторы по умолчанию вызываются во время инициализации по умолчанию и значимой инициализации.
Неявный конструктор по умолчанию
Если для типа класса не предоставлено ни одного объявленного пользователем конструктора, компилятор всегда объявляет конструктор по умолчанию как 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не имеет виртуальных базовых классов.
| (с 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 | инициализаторы членов по умолчанию не оказывали влияния на то, удаляется ли неявно объявленный конструктор по умолчанию для объединения | они препятствуют удалению неявно объявленного конструктора по умолчанию |
См. также
© cppreference.com
Licensed under the Creative Commons Attribution-ShareAlike Unported License v3.0.
https://en.cppreference.com/w/cpp/language/default_constructor