- Конструктор по умолчанию (Default constructor);
- Деструктор (Destructor);
- Конструктор копирования (Copy constructor);
- Оператор копирующего присваивания (Copy assignment);
- Конструктор переноса (Move constructor);
- Оператор переносящего присваивания (Move assignment);
Или в коде:
struct MyStruct { MyStruct() = default; ~MyStruct() = default; MyStruct(const MyStruct &) = default; MyStruct &operator=(const MyStruct &) = default; MyStruct(MyStruct &&) = default; MyStruct &operator=(MyStruct &&) = default; };Каждая из этих функций может быть:
- Не объявлена;
- Может быть сгенерирована компилятором:
- Как default - вызывает соответствующие функции для членов. Для конструктора - конструкторы членов, для оператора присваивания - операторы присваивания членов и т.д.
- Как delete - если соответствующая функция у члена объявлена как delete или функция не может быть сгенерирована. Например для оператора присваивания член может иметь оператор присваивания объявленный как delete, или объект не может копироваться, т.к. содержит ссылку.
- Может быть объвлена явно программистом:
- Как default;
- Как delete;
- С телом функции;
Разница между "не объявлена" и объявлена с delete в том, что не объявленная функция не участвует в разрешении перегрузки.
Например класс:
struct MyStruct { template <typename... Args> MyStruct(Args...) { } };может быть создан вызовом конструктора без параметров, т.к. конструктор по умолчанию не объявлен, и не участвует в разрешении перегрузки.
Но такой класс:
struct MyStruct { template <typename... Args> MyStruct(Args...) { } MyStruct() = delete; };создать вызовом конструктора без параметров не получится, т.к. конструктор по умолчанию объявлен и участвует в разрешении перегрузки, и при этом он объявлен как delete.
При этом стоить помнить одно правило - если перемещающие функции объявленны компиляторм как delete, они не участвуют в разрешении перегрузки, не смотря на факт объвления.
Когда и какие функции компилятор генерирует сам, а когда объявляет их как delete?
Объявленный конструктор по умолчанию - остальные 5 функций объявляются компилятором как default:
struct MyStruct { MyStruct() = default; ~MyStruct() = default; MyStruct(const MyStruct &) = default; MyStruct &operator=(const MyStruct &) = default; MyStruct(MyStruct &&) = default; MyStruct &operator=(MyStruct &&) = default; };Объявленный деструктор - конструктор перемещения и перемещающий оператор присваивания становятся не объявленными, остальные функции объявляются компилятором как default:
struct MyStruct { MyStruct() = default; ~MyStruct() = default; MyStruct(const MyStruct &) = default; MyStruct &operator=(const MyStruct &) = default; };Объявленный конструктор копирования - конструктор по умолчанию, конструктор перемещения и перемещающий оператор присваивания становятся не объявленными, остальные функции объявляются компилятором как default:
struct MyStruct { ~MyStruct() = default; MyStruct(const MyStruct &) = default; MyStruct &operator=(const MyStruct &) = default; };Объявленный копирующий оператор присваивания - конструктор перемещения и перемещающий оператор присваивания становятся не объявленными, остальные функции объявляются компилятором как default:
struct MyStruct { MyStruct() = default; ~MyStruct() = default; MyStruct(const MyStruct &) = default; MyStruct &operator=(const MyStruct &) = default; };Объявленный конструктор перемещения - конструктор по умолчанию и перемещающий оператор присваивания становятся не объявленным, деструктор объявляется компилятором как default, остальные функции объявляются компилятором как delete.
struct MyStruct { ~MyStruct() = default; MyStruct(const MyStruct &) = delete; MyStruct &operator=(const MyStruct &) = delete; MyStruct(MyStruct &&) = default; };Объявленный перемещающий оператор присваивания - конструктор по умолчанию и деструктор объявляется компилятором как default, конструктор копирования и оператор копирующего присваивания объявляются компилятором как delete, конструктор перемещения становится не объявленным.
struct MyStruct { MyStruct() = default; ~MyStruct() = default; MyStruct(const MyStruct &) = delete; MyStruct &operator=(const MyStruct &) = delete; MyStruct &operator=(MyStruct &&) = default; };
Комментариев нет:
Отправить комментарий