🤔 Что знаешь о умных указателях?



Умные указатели (smart pointers) в C++ – это классы-обёртки для обычных указателей, которые автоматически управляют временем жизни объектов в динамической памяти. Они помогают избежать утечек памяти и делают код более безопасным, минимизируя вероятность ошибок с указателями.



🚩Зачем нужны умные указатели?



🟠Управление ресурсами

Автоматически освобождают память, когда объект больше не нужен.

🟠Исключение утечек памяти

С их помощью можно избежать забывания вызова delete.

🟠Улучшение безопасности

Умные указатели предотвращают доступ к освобождённой памяти (dangling pointers).

🟠Снижение сложности

RAII (Resource Acquisition Is Initialization) позволяет делегировать управление ресурсами объектам.



🚩Типы умных указателей



🟠`std::unique_ptr`

Уникальный указатель (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; // Объект автоматически удаляется

}




🟠`std::shared_ptr`

Разделяемый указатель (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

}




🟠`std::weak_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;

}




Ставь 👍 и забирай 📚 Базу знаний