← Назад к вопросам
Что такое умные указатели?
1.6 Junior🔥 261 комментариев
#Умные указатели и управление памятью
Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI21 мар. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
# Умные указатели в C++
Умные указатели (smart pointers) — это шаблонные классы, которые обёртывают сырые указатели и автоматизируют управление памятью через RAII паттерн. Это одна из ключевых инноваций Modern C++, избавляющая от необходимости вручную вызывать delete.
Основные типы
std::unique_ptr
Уникальный указатель с эксклюзивным владением ресурсом:
std::unique_ptr<MyClass> ptr1(new MyClass());
std::unique_ptr<MyClass> ptr2 = std::move(ptr1);
// ptr1 теперь nullptr, ptr2 владеет объектом
// При выходе ptr2 из области видимости объект удаляется
Особенности:
- Нулевые накладные расходы (zero-overhead abstraction)
- Не может быть скопирован (только перемещён)
- Идеален для исключительного владения
- Размер = размер указателя (обычно 8 байт)
std::shared_ptr
Разделённое владение ресурсом через подсчёт ссылок (reference counting):
std::shared_ptr<MyClass> ptr1(new MyClass());
std::shared_ptr<MyClass> ptr2 = ptr1; // копируем
// use_count() вернёт 2
// Объект удалится только когда последний shared_ptr выйдет из области видимости
Особенности:
- Можно копировать
- Потокобезопасное изменение счётчика (atomic operations)
- Требует дополнительную память на управляющий блок (control block)
- Размер = 2 указателя (16 байт)
Лучшие практики
Когда использовать unique_ptr
- Функция владеет объектом и несет ответственность за его жизненный цикл
- Контейнеры с единственным владельцем
- Вывод: ищите
unique_ptrв сигнатурах функций как знак ответственности
std::unique_ptr<DataBuffer> readFileData(const std::string& filename) {
auto buffer = std::make_unique<DataBuffer>();
// заполняем buffer
return buffer; // move semantics автоматически
}
Когда использовать shared_ptr
- Граф объектов с множественным владением (например, в играх или GUI)
- Callback'и с длительным жизненным циклом
- Аккуратно используй в многопоточных системах
class Observer {
std::shared_ptr<DataSource> source;
public:
Observer(std::shared_ptr<DataSource> src) : source(src) {}
};
Хитрости и ошибки
Циклические ссылки
Опасная ситуация с shared_ptr:
struct A { std::shared_ptr<B> b; };
struct B { std::shared_ptr<A> a; }; // утечка памяти!
// Решение: используй std::weak_ptr для обратных ссылок
struct B { std::weak_ptr<A> a; }; // не увеличивает счётчик
make_unique и make_shared
Всегда предпочитай конструкторам new:
// Хорошо: одна выделение памяти
auto ptr = std::make_unique<MyClass>(arg1, arg2);
// Менее эффективно: два выделения
std::unique_ptr<MyClass> ptr(new MyClass(arg1, arg2));
Производительность
unique_ptr: нулевые накладные расходыshared_ptr: атомарные операции (дорого в tight loops)- В критичных местах предпочитай
unique_ptrили stack allocation
Умные указатели — это инструмент для безопасного и эффективного C++ кода.