История умных указателей (smart pointers) в C++ связана с необходимостью управления динамической памятью и улучшением безопасности работы с указателями. Они появились как способ автоматизировать управление памятью и избежать ошибок, таких как утечки памяти, двойное освобождение или использование освобожденной памяти.
В языке C++ динамическая память выделяется с помощью
new
и освобождается с помощью delete
. Однако ручное управление памятью приводит к ошибкам:Утечки памяти: забыли вызвать
delete
, и память остаётся занятой.Двойное освобождение: дважды вызвали
delete
на одном указателе.Использование освобождённой памяти: доступ к указателю после
delete
.Эти проблемы стали мотиватором для появления решений, которые бы автоматически управляли памятью.
До стандартизации разработчики часто писали свои собственные классы для управления динамической памятью. Такой класс оборачивал указатель и вызывал
delete
в своём деструкторе:class SmartPointer {
int* ptr;
public:
explicit SmartPointer(int* p = nullptr) : ptr(p) {}
~SmartPointer() { delete ptr; }
int& operator*() { return *ptr; }
int* operator->() { return ptr; }
};
В библиотеке Boost появились первые стандартизированные умные указатели:
boost::shared_ptr
: реализует совместное владение указателем (reference counting).boost::scoped_ptr
: уникальное владение (аналог будущего std::unique_ptr
).boost::weak_ptr
: слабая ссылка для работы с циклическими зависимостями.Boost сыграл огромную роль в стандартизации умных указателей, так как многие из них легли в основу C++11.
Стандарт C++11 ввёл библиотеку
<memory>
, которая предоставляет три типа умных указателей:std::unique_ptr
:Гарантирует уникальное владение ресурсом.
Замена для обычных указателей с более строгими гарантиями.
Не поддерживает копирование, только перемещение.
std::unique_ptr<int> ptr(new int(5));
std::shared_ptr
:Совместное владение ресурсом через подсчёт ссылок.
Освобождает память, когда последний
shared_ptr
указывает на объект.std::shared_ptr<int> sp1 = std::make_shared<int>(10);
std::weak_ptr
:Не увеличивает счётчик ссылок в
std::shared_ptr
.Используется для работы с циклическими зависимостями.
std::weak_ptr<int> wp = sp1;
С выходом C++14, C++17 и C++20 умные указатели остаются важной частью языка. Они используются для:
Ресурсного управления (RAII).
Устранения утечек памяти.
Упрощения кода.
Ставь 👍 и забирай 📚 Базу знаний