TGViewer
Грокаем C++ Грокаем C++ @grokaemcpp · 9.37K subscribers
Post #41 1.07K
Как правильно запретить объекту копироваться

Бывают такие ситуации, когда объект владеет каким-то ресурсом единолично, то есть имеет над ним так называемый ownership. В этом случае время жизни и использования ресурса совпадает с временем жизни объекта, а использование этого же самого ресурса другим объектом будет приносить странные side effect’ы. Например у нас есть класс, который содержит файл в качестве поля и который открывает этот файл в конструкторе и закрывает в деструкторе. Что должно происходить при копировании объекта этого класса? Должен ли файл ещё раз открываться или в начале в копируемом объекте закрываться, а потом открываться в скопированном? Все варианты выглядят выстрелом в хлебало, поэтому логично запретить таким объектам копироваться.

Как это сделать? Самое широкоиспользуемое решение - объявить конструктор копирования и оператор присваивания приватными и жить счастливо. Никто снаружи класса не сможет получить доступ к этим специальным методам, а при попытке будет ошибка компиляции. Но это только снаружи класса. Внутри класса-то можно использовать приватные поля и методы. И тут уже огромный простор для ошибок, в зависимости от того, как вы определили специальные методы.

Такой код

class NonCopyable {
private:
NonCopyable( const NonCopyable& ) {}
void NonCopyable::operator=( const NonCopyable& ) {}
};

void NonCopyable::SomeOtherMehod() {
callSomething( *this );
}

Приведёт к вызову копирующего конструктора и копированию всех полей, что ведёт к неопределенному поведению.

Но С++11 подарил нам прекрасную фича - можно пометить любую функцию как = delete и компилятор просто не будет генерировать код для неё. Поэтому такие функции физически не могут быть вызваны. Пометив наши методы удаленными, мы уберём возможность любой сущности их вызывать и сильно обезопасим код.

К тому же, использование этой фичи повышает читаемость кода. А так как пометить удаленной можно любую функцию, то можно удалить ненужную перегрузку или запретить вызывать функцию с ошибочным приведением параметров.

Modern C++ - сила.

Stay cool.

#cppcore #cpp11 #goodpractice
  • ❤ 17
  • 👍 6
  • 🔥 4
More from @grokaemcpp
  1. Oct 8, 2026​​Strict weak ordering #опытным На первый взгляд, всё выглядит рабочим: мы создаём 40 зака…
  2. Oct 7, 2026​​Где-то баг... #опытным Вот вам код: struct Order { int price; int id; }; int main() { st…
  3. Oct 5, 2026Откуда spurious wakeup на кондваре? #опытным У кондваров есть метод std::condition_variabl…
  4. Oct 1, 2026​​Stacktrace. Tips #опытным Чтобы полноценно работать со стандартными трейсами, нужно знат…
  5. Sep 28, 2026​​Stacktrace #опытным Одна из проблема исключений - непонятно, откуда оно прилетело. Ну да…
  6. Sep 25, 2026​​std::spanstream #опытным Радостная весть для всех, кто пользуется iostreams! В C++23 доб…
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →