Специальные функции-члены
В C++ программирования языке специальные функции-члены [ 1 ] — это функции , которые компилятор автоматически генерирует, если они используются, но не объявлены явно программистом. Автоматически генерируемые специальные функции-члены:
- Конструктор по умолчанию , если другой конструктор явно не объявлен.
- Конструктор копирования , если конструктор перемещения и оператор присваивания перемещения явно не объявлены.
- Если деструктор объявлен, создание конструктора копирования устарело ( C++11 , предложение N3242 [ 2 ] ).
- Конструктор перемещения , если конструктор копирования, оператор присваивания копирования, оператор присваивания перемещения и деструктор явно не объявлены.
- Копировать оператор присваивания , если конструктор перемещения и оператор перемещения перемещения явно не объявлены.
- Если объявлен деструктор, создание оператора присваивания копии не рекомендуется.
- Оператор перемещения присваивания , если конструктор копирования, оператор присваивания копирования, конструктор перемещения и деструктор явно не объявлены.
- Деструктор
В этих случаях сгенерированные компилятором версии этих функций выполняют почленную операцию. Например, деструктор, созданный компилятором, уничтожит каждый подобъект (базовый класс или член) объекта.
Функции, сгенерированные компилятором, будут public
, не виртуальный [ 3 ] а конструктор копирования и операторы присваивания получат const&
параметров (и не иметь альтернативных правовых форм ). [ 4 ]
Пример
[ редактировать ]В следующем примере показаны два класса: Явный , для которого все специальные функции-члены явно объявлены и Неявный , для которого ничего не объявлено.
#include <iostream>
#include <string>
#include <utility>
class Explicit {
public:
Explicit() { std::cout << "Default constructor " << message_ << '\n'; }
explicit Explicit(std::string message) : message_(std::move(message)) {
std::cout << "Non-default constructor " << message_ << '\n';
}
Explicit(const Explicit& other) {
std::cout << "Copy constructor " << message_ << '\n';
*this = other; // invoke copy assignment operator
}
Explicit& operator=(const Explicit& other) {
std::cout << "Copy assignment operator " << message_ << '\n';
if (this != &other) {
message_ = other.message_;
}
return *this;
}
Explicit(Explicit&& other) noexcept {
std::cout << "Move constructor " << message_ << '\n';
*this = std::move(other); // invoke move assignment operator
}
Explicit& operator=(Explicit&& other) noexcept {
std::cout << "Move assignment operator " << message_ << '\n';
if (this != &other) {
message_ = std::move(other.message_);
}
return *this;
}
~Explicit() { std::cout << "Destructor " << message_ << '\n'; }
private:
friend class Implicit;
std::string message_;
};
class Implicit : public Explicit {
public:
void Spew() {
std::cout << "Implicit(" << message_ << ", " << member_.message_ << ")\n";
}
private:
Explicit member_;
};
Подписи
[ редактировать ]Вот сигнатуры специальных функций-членов:
Функция | синтаксис класса MyClass |
---|---|
Конструктор по умолчанию | MyClass();
|
Копировать конструктор | MyClass(const MyClass& other);
|
Переместить конструктор | MyClass(MyClass&& other) noexcept;
|
Копировать оператор присваивания | MyClass& operator=(const MyClass& other);
|
Переместить оператор присваивания | MyClass& operator=(MyClass&& other) noexcept;
|
Деструктор | virtual ~MyClass();
|
С++03
[ редактировать ]В C++03 до введения семантики перемещения (в C++11) специальные функции-члены [ 5 ] были:
- Конструктор по умолчанию (если другой конструктор явно не объявлен)
- Копировать конструктор
- Копировать оператор присваивания
- Деструктор
Ссылки
[ редактировать ]- ^ ИСО/МЭК (2011). ISO/IEC 14882:2011 (3-е изд.). ИСО/МЭК. стр. §12.
- ^ «Соблюдение правила нуля» .
- ^ За исключением деструктора, если базовый класс уже имеет виртуальный деструктор.
- ^ Аналогично, конструктор перемещения/оператор присваивания получит
&&
параметры вместо альтернатив. - ^ ИСО/МЭК (1998). Международный стандарт ISO/IEC 14882: Языки программирования — C++ = Языки программирования — C++ (1-е изд.). ИСО/МЭК. стр. §12. OCLC 71718919 .