Default constructors
Конструктор по умолчанию — это конструктор , который может быть вызван без аргументов.
Содержание |
Синтаксис
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 | - | parameter list , в котором все параметры (кроме parameter packs ) (since C++11) имеют default arguments |
| function-body | - | function body конструктора по умолчанию |
Объяснение
Конструкторы по умолчанию вызываются при инициализации по умолчанию и инициализации значением .
Неявно объявленный конструктор по умолчанию
Если для типа класса не объявлен пользовательский конструктор или шаблон конструктора, компилятор неявно объявит конструктор по умолчанию как inline public член своего класса.
Неявно объявленный (или defaulted при первом объявлении) конструктор по умолчанию имеет спецификацию исключений, как описано в dynamic exception specification (until C++17) noexcept specification (since C++17) .
Неявно определённый конструктор по умолчанию
Если конструктор является неявно объявленным (до C++11) неявно объявленный или явно заданный по умолчанию конструктор не определен как удаленный (начиная с C++11) , он неявно определяется компилятором при odr-использовании или необходимости для константного вычисления или когда он явно задан по умолчанию после первого объявления (начиная с C++11) .
|
Если конструктор по умолчанию
union-подобного класса
|
(since C++26) |
Неявно определенный конструктор по умолчанию (до C++26) В противном случае, неявно определенный конструктор по умолчанию (начиная с C++26) имеет тот же эффект, что и пользовательский конструктор с пустым телом и пустым списком инициализации. То есть он вызывает конструкторы по умолчанию базовых классов и нестатических членов данного класса. Типы классов с пустым предоставленным пользователем конструктором могут обрабатываться иначе, чем типы с неявно определенным конструктором по умолчанию, во время value initialization .
|
Если это удовлетворяет требованиям constexpr конструктора (до C++23) constexpr функции (начиная с C++23) , то сгенерированный конструктор является constexpr . Если присутствуют некоторые пользовательские конструкторы, пользователь всё ещё может принудительно заставить компилятор автоматически сгенерировать конструктор по умолчанию, который в противном случае был бы неявно объявлен, с помощью ключевого слова default . |
(начиная с C++11) |
Удаленный конструктор по умолчанию
Неявно объявленный или явно заданный конструктор по умолчанию для класса
Если пользовательские конструкторы отсутствуют и неявно объявленный конструктор по умолчанию не является тривиальным, пользователь все еще может запретить автоматическую генерацию неявно определенного конструктора по умолчанию компилятором с помощью ключевого слова delete . |
(since C++11) |
Тривиальный конструктор по умолчанию
Конструктор по умолчанию для класса
T
является тривиальным, если выполняются все следующие условия:
- Конструктор является неявно-объявленным (до C++11) не предоставленным пользователем (начиная с C++11) .
-
Tне имеет виртуальных функций-членов. -
Tне имеет виртуальных базовых классов.
|
(начиная с C++11) |
-
Каждый прямой базовый класс
Tимеет тривиальный конструктор по умолчанию.
|
(до C++26) |
|
(начиная с C++26) |
Тривиальный конструктор по умолчанию — это конструктор, который не выполняет никаких действий. Все типы данных, совместимые с языком C (POD-типы), являются тривиально конструируемыми по умолчанию.
Подходящий конструктор по умолчанию
|
Конструктор по умолчанию является подходящим, если он либо объявлен пользователем, либо одновременно неявно объявлен и может быть определен. |
(until C++11) |
|
Конструктор по умолчанию является подходящим, если он не удален. |
(since C++11)
(until C++20) |
|
Конструктор по умолчанию является подходящим, если удовлетворены все следующие условия:
|
(since C++20) |
Тривиальность подходящих конструкторов по умолчанию определяет, является ли класс типом с неявным временем жизни , и является ли класс тривиально копируемым типом .
Примечания
| Макрос тестирования возможностей | Значение | Стандарт | Возможность |
|---|---|---|---|
__cpp_trivial_union
|
202502L
|
(C++26) | Ослабление требований тривиальности для специальных функций-членов объединений |
Пример
struct A { int x; A(int x = 1): x(x) {} // пользовательский конструктор по умолчанию }; struct B : A { // B::B() неявно определяется, вызывает 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++.
| DR | Applied to | Behavior as published | Correct behavior |
|---|---|---|---|
| CWG 1353 | C++11 |
условия, при которых неявно объявленные конструкторы по умолчанию
определяются как удалённые, не учитывали многомерные массивы |
учитывать эти типы |
| CWG 2084 | C++11 |
инициализаторы членов по умолчанию не влияли на то,
является ли конструктор по умолчанию объединения удалённым |
они предотвращают удаление
конструктора по умолчанию |
| CWG 2595 | C++20 |
конструктор по умолчанию не был пригоден, если существует
другой конструктор по умолчанию, который более ограничен, но не удовлетворяет своим ассоциированным ограничениям |
он может быть пригоден в этом случае |
| CWG 2871 | C++98 |
конструктор по умолчанию был бы неявно объявлен
даже при наличии пользовательского шаблона конструктора |
неявное объявление отсутствует
в этом случае |