unique_ptr: исключительное владение
Выражайте семантику единственного владельца с помощью unique_ptr и типов, поддерживающих только перемещение.
«unique_ptr: исключительное владение» — бесплатный урок C++ Academy на CoddyKit. Это урок 2 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения C++ Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс C++ Academy содержит 4 уроков всего.
Умный указатель с единственным владельцем
std::unique_ptr<T> владеет одним объектом в куче. Когда unique_ptr уничтожается, он удаляет объект. Копировать его нельзя — его можно только перемещать.
Создание unique_ptr
Используйте std::make_unique (C++14) — это безопасно при работе с исключениями и лаконично.
#include <memory>
auto w = std::make_unique<Widget>(); // default-constructed
auto p = std::make_unique<Point>(3, 4); // forwarded argsИспользование как указателя
unique_ptr поддерживает обычные операции с указателями.
auto p = std::make_unique<Point>(3, 4);
std::cout << p->x; // arrow access
std::cout << (*p).y; // dereference
if (p) std::cout << "non-null";Копировать нельзя — перемещать можно
Копирование означало бы наличие двух владельцев, что нарушает принцип «единственности». Перемещение передаёт владение.
std::unique_ptr<int> a = std::make_unique<int>(1);
std::unique_ptr<int> b = std::move(a);
// a is now empty, b owns the intПередача в функции
По значению (с std::move): передача владения. По ссылке: заимствование без владения.
void consume(std::unique_ptr<Widget> w); // takes ownership
void inspect(const Widget& w); // borrows
auto w = std::make_unique<Widget>();
consume(std::move(w));
// w is now empty
inspect(*w); // (after re-creating)Возврат из функций
Функция, которая выделяет объект и возвращает владение им, должна возвращать std::unique_ptr.
std::unique_ptr<Widget> create() {
return std::make_unique<Widget>();
}Сброс и освобождение владения
reset() удаляет текущий объект и при необходимости принимает владение новым. release() отказывается от владения и возвращает необработанный указатель.
auto p = std::make_unique<int>(10);
p.reset(new int(20)); // delete the old, own the new
int* raw = p.release(); // p is now empty
delete raw; // caller must deleteget(): заимствование необработанного указателя
get() возвращает необработанный указатель, не отказываясь от владения. Используйте его для взаимодействия без передачи владения.
auto p = std::make_unique<int>(42);
legacy_api(p.get()); // p still owns itunique_ptr для массивов
Для массивов используйте unique_ptr<T[]>. Доступ по индексу выполняется с помощью []; при уничтожении вызывается delete[].
auto arr = std::make_unique<int[]>(10);
arr[0] = 99;
std::cout << arr[0];Пользовательские средства удаления
Задайте пользовательское средство удаления в качестве параметра шаблона, если ресурсом является не необработанная память, а дескриптор файла или ресурс ОС.
auto closer = [](FILE* f) { if (f) std::fclose(f); };
std::unique_ptr<FILE, decltype(closer)> file(std::fopen("a.txt","r"), closer);Производительность
При использовании средства удаления по умолчанию unique_ptr имеет тот же размер и скорость, что и необработанный указатель, — никаких дополнительных затрат.
Быстрая проверка
Почему std::unique_ptr запрещает копирование?
Итоги
std::unique_ptr — умный указатель по умолчанию: никаких дополнительных затрат, исключительное владение, возможность перемещения, но не копирования. Для создания предпочитайте std::make_unique.
Часто задаваемые вопросы
Урок «unique_ptr: исключительное владение» бесплатный?
Да — полный текст урока «unique_ptr: исключительное владение» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс C++ Academy, подпишись на CoddyKit PRO. Курс C++ Academy содержит 4 уроков всего.
Чему я научусь в уроке «unique_ptr: исключительное владение»?
Выражайте семантику единственного владельца с помощью unique_ptr и типов, поддерживающих только перемещение. Ты практикуешь C++ Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.
Нужен ли мне опыт, чтобы начать C++ Academy?
Предыдущий опыт не требуется. C++ Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 2 из 4.
Сколько времени занимает урок «unique_ptr: исключительное владение»?
Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.
Можно ли писать и запускать код в этом уроке C++ Academy?
Да. Каждый урок C++ Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.
Все уроки этого курса
- Почему умные указатели заменяют обычные new и delete
- unique_ptr: исключительное владение
- shared_ptr и weak_ptr: совместное владение
- Пользовательские удалители и функции make