Ответ
std::unique_ptr обеспечивает эксклюзивное владение ресурсом через два ключевых механизма:
- Запрет копирования — конструктор копирования и оператор присваивания копированием объявлены как
= delete. - Перемещающая семантика — владение можно передать другому
unique_ptrс помощьюstd::move(). После перемещения исходный указатель становитсяnullptr.
Пример передачи владения:
std::unique_ptr<int> ptr1 = std::make_unique<int>(42);
// std::unique_ptr<int> ptr2 = ptr1; // Ошибка компиляции: копирование запрещено
std::unique_ptr<int> ptr2 = std::move(ptr1); // OK: владение передано
// Теперь ptr1.get() == nullptr, а ptr2 владеет ресурсом
Почему это важно:
- Гарантирует, что ресурс будет освобожден ровно один раз при разрушении владеющего
unique_ptr. - Не имеет накладных расходов времени выполнения (в отличие от
std::shared_ptrс подсчетом ссылок). - Позволяет использовать пользовательские удалители (custom deleter) для сложных ресурсов (например, файловых дескрипторов,
SDL_Surface*).
Ответ 18+ 🔞
А, ну вот, опять про эти умные указатели. Слушай, я тебе как человек, который уже наступил на все грабли, объясню, что к чему. std::unique_ptr — это как твой личный, блядь, крутой внедорожник. Ты на нём один ездишь, ключики у тебя в кармане. И главное правило — его нельзя просто так скопировать, типа сделать второй такой же ключ от двери. Это, ёпта, запрещено на уровне компилятора, конструкторы копирования просто удалены, и всё тут. Попробуешь — получишь ошибку, и будешь сидеть, чесать репу.
Но! Если ты решил, что надоел тебе этот джип, жрёт бензина дохуя, то ты можешь передать его другому чуваку. Вот буквально взять и отдать ключи. Это называется перемещающая семантика, через std::move(). После этого твой старый указатель становится пустым, nullptr, то есть нихуя не указывает, а весь ресурс теперь у нового владельца. Красота, да?
Смотри, как это выглядит в коде, тут всё просто:
std::unique_ptr<int> ptr1 = std::make_unique<int>(42); // Твой новенький интеджер
// std::unique_ptr<int> ptr2 = ptr1; // Ошибка компиляции! Хуй тебе, а не копия. Забудь.
std::unique_ptr<int> ptr2 = std::move(ptr1); // Окей! Владение передано, как ключи от машины.
// Теперь ptr1.get() == nullptr, нихуя нет, а ptr2 владеет ресурсом.
А зачем весь этот цирк, спросишь? Да затем, чувак, чтобы не было пиздеца с утечками памяти. Гарантия железная: ресурс освободится ровно один раз, когда умрёт тот unique_ptr, который им сейчас владеет. Никаких танцев с бубном, никакого подсчёта ссылок, как у его братана shared_ptr, который жрёт процессорное время. Всё быстро, чётко, по-военному.
И ещё фишка — можно свой собственный удалитель прикрутить. Ну, то есть не только память из кучи чистить, а, например, файл закрыть или какую-нибудь графическую поверхность в SDL уничтожить. Гибко, мощно, ядрёна вошь! В общем, учи матчасть, без этого сейчас нихуя не напишешь.