- Конструктор по умолчанию (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;
};
Комментариев нет:
Отправить комментарий