Умные указатели (smart pointers) в C++ – это классы-обёртки для обычных указателей, которые автоматически управляют временем жизни объектов в динамической памяти. Они помогают избежать утечек памяти и делают код более безопасным, минимизируя вероятность ошибок с указателями.
Автоматически освобождают память, когда объект больше не нужен.
С их помощью можно избежать забывания вызова
delete
.Умные указатели предотвращают доступ к освобождённой памяти (dangling pointers).
RAII (Resource Acquisition Is Initialization) позволяет делегировать управление ресурсами объектам.
Уникальный указатель (unique pointer) обладает единственным владельцем объекта. После передачи владения объектом другому
std::unique_ptr
, исходный указатель становится недействительным.Обеспечивает строгую семантику владения.
Лёгкий, так как не использует счётчики ссылок.
Не копируемый, но перемещаемый.
#include <iostream>
#include <memory>
class MyClass {
public:
MyClass() { std::cout << "Создан объект\n"; }
~MyClass() { std::cout << "Удалён объект\n"; }
};
int main() {
std::unique_ptr<MyClass> ptr1 = std::make_unique<MyClass>(); // Владеет объектом
std::unique_ptr<MyClass> ptr2 = std::move(ptr1); // Передача владения
// ptr1 теперь nullptr, ptr2 владеет объектом
return 0; // Объект автоматически удаляется
}
Разделяемый указатель (shared pointer) поддерживает разделённое владение объектом. Указатель освобождает память только тогда, когда все
std::shared_ptr
, ссылающиеся на объект, будут уничтожены.Использует счётчик ссылок (reference count).
Обеспечивает совместное использование ресурса несколькими владельцами.
#include <iostream>
#include <memory>
class MyClass {
public:
MyClass() { std::cout << "Создан объект\n"; }
~MyClass() { std::cout << "Удалён объект\n"; }
};
int main() {
std::shared_ptr<MyClass> ptr1 = std::make_shared<MyClass>();
std::shared_ptr<MyClass> ptr2 = ptr1; // Разделение владения
// Указатель ptr1 и ptr2 указывают на один и тот же объект
return 0; // Объект удаляется после уничтожения последнего shared_ptr
}
Слабый указатель (weak pointer) не увеличивает счётчик ссылок. Используется для предотвращения циклических зависимостей между
std::shared_ptr
.Ссылается на объект, которым управляет
std::shared_ptr
.Не владеет объектом.
Может проверять существование объекта с помощью
expired()
.#include <iostream>
#include <memory>
class MyClass {
public:
MyClass() { std::cout << "Создан объект\n"; }
~MyClass() { std::cout << "Удалён объект\n"; }
};
int main() {
std::shared_ptr<MyClass> shared = std::make_shared<MyClass>();
std::weak_ptr<MyClass> weak = shared; // Слабая ссылка
if (auto ptr = weak.lock()) { // Проверка на существование
std::cout << "Объект существует\n";
}
shared.reset(); // Освобождаем shared_ptr
if (weak.expired()) {
std::cout << "Объект удалён\n";
}
return 0;
}
Ставь 👍 и забирай 📚 Базу знаний