avatar
Грокаем C++
@grokaemcpp
30.06.2026 09:00
​​Специальные методы классов
#новичкам

Помимо обычных методов, которые позволяют классу выполнить какую-то полезную работу, существуют методы, которые менеджерят самими объектами. Среди них выделяют так называемые "специальные" методы классов, которые компилятор неявно за вас сгенерирует. Давайте перечислим их и поясним, почему компилятор способен вообще для них написать код:

1️⃣ Конструктор по-умолчанию. Дефолтный конструктор без аргументов. Мы уже подробно разбирали его в предыдущих постах, останавливаться не будем.

Любые параметрические конструкторы не могут быть специальными методами классов, аля не могут быть сгенерированы компилятором, потому что он не знает, что в общем случае нужно делать с параметрами.

2️⃣ Деструктор. Он семантически разрушает объект. Забирает у него память, закрывает дескрипторы и соединения, высасывает жизнь, отбирает квартиру, машину, жену и собаку и передает это государству операционной системе.

Как так получается, что компилятор вообще способен сам сгенерировать код деструктора объекта, который владеет ресурсами?

Все благодаря RAII и способности деструктора вызывать деструкторы своих полей. Если в вашем классе Foo содержится std::vector или std::unique_ptr, вам не нужно задумываться о менеджменте памяти, авторы этих классов уже все придумали за вас. Вам нужно лишь вызывать их деструктор, что деструктор Foo делает автоматически.

using File = std::unique_ptr<FILE, decltype(&std::fclose)>;

struct Foo {
std::vector<int> numbers;
File file;
// no explicit destructor ~Foo() {}
};

void foo() {
Foo obj = {{1, 2, 3, 4, 5, 6, 7, 8, 9}, {std::fopen("example.txt", "r"), &std::fclose}};
} // destroy obj here


3️⃣ Копирующий конструктор
4️⃣ Перемещающий конструктор

Для этой пары конструкторов правило единое: самое простое решение для копирования/перемещения объекта - это просто скопировать/переместить все его поля в другой объект. Компилятор с этим вполне справится сам: вызовет пачку нужных конструкторов да и все.

Естественно, если хотя бы у одного поля вашего класса не будет копирующего/перемещающего конструктора, сам ваш класс потеряет возможность копироваться/перемещаться.

struct Foo {
std::vector<int> numbers;
// no explicit copy/move constructors
// Foo(const Foo& other) {...}
// Foo(Foo&& other) {...}
};

void foo() {
Foo obj = {{1, 2, 3, 4, 5, 6, 7, 8, 9}};
Foo copied_in_obj = obj; // copy obj
Foo moved_in_obj = std::move(obj); // move from obj


5️⃣ Копирующий оператор присваивания
6️⃣ Перемещающий оператор присваивания

Это операторы, которые вызываются тогда, когда вы хотите передать уже существующему объекту значение другого объекта.

И вот здесь интересная комбинация.

Чтобы присвоить значение, нужно уметь разрушать текущее значение и передавать другое значение. То есть автоматическая генерация присваивания возможно благодаря тому, что компилятор сам умеет разрушать объект и копировать/присваивать значения полей.

Чуть остановимся на синтаксисе:

Foo a, b;
a = b; // copy assign
a = std::move(b); // move assign

Foo a1 = b; // THIS IS NOT AN ASSIGN


Последняя операция не является присваиванием - это вызов конструктора(в этом случае копирующего). Если объект только создается, то это всегда вызов конструктора.

Теперь примерчик:

struct Foo {
std::vector<int> numbers;
// no explicit copy/move constructors
// Foo& operator=(const Foo& other) {...}
// Foo& operator=(Foo&& other) {...}
};

void foo() {
Foo forward = {{1, 2, 3, 4, 5, 6, 7, 8, 9}};
Foo backward = {{9, 8, 7, 6, 5, 4, 3, 2, 1}};
Foo obj; // created obj here
obj = forward; // copy assign forward to obj
obj = std::move(backward); // move assign backward to obj


Итого: всего 6 специальных методов класса. Не больше, не меньше. На собесах любят про это спрашивать, так что забирайте.

Be special. Stay cool.

#cppcore #cpp11 #interview
🔥 12
8
👍 7
8 21 3K

Обсуждение 8

Обсуждение не доступно в веб-версии. Чтобы написать комментарий, перейдите в приложение Telegram.

Обсудить в Telegram

Грокаем C++

9.3K
Два сеньора C++ - Владимир и Денис - отныне ваши гиды в этом дремучем мире плюсов.

По всем вопросам (+ реклама) @ninjatelegramm

Менеджер: @Spiral_Yuri
Реклама: https://telega.in/c/grokaemcpp
Мы на TGstat: https://tgstat.ru/channel/@grokaemcpp/stat
Открыть в Telegram