42. C++ Умные указатели. Smart pointers.

Умные указатели. Smart pointers.

В языке C++ одной из главных проблем являются утечки памяти, для упрощения работы с ними используются умные указатели.
По сути умный указатель – шаблонный класс в конструкторе которого «захватывается» указатель на область в динамической памяти, а в деструкторе область освобождается.

В чем смысл? Как известно деструктор вызывается при выходе из зоны видимости функции/программы и тд., т.е. в момент вызова деструктора мы уже знаем что не будем работать с этим классом, а т.к. в деструкторе есть оператор delete или delete[], то мы освобождаем память.

Главная проблема умных указателей – работа со ссылками на одну и тоже область в памяти (т.к. вызовется деструктор на одну и туже область в памяти и будет ошибка), для борьбы с подобным используются умные указатели из библиотеки <memory>

В C++ есть стандартная библиотека для деструкторов
#include <memory>

Внутри есть несколько видов умных указателей:

auto_ptr:
При присвоении двум указателям ссылки на один объект в памяти например:

auto_ptr<int> autoPtr_1(new int(10));
auto_ptr<int> autoPtr_2(autoPtr_1);

ссылку будет иметь лишь последний автоматический указатель, а все предыдущиебудут иметь null/nullptr

unique_ptr:
При присвоении двум указателям ссылки на один объект в памяти например:

unique_ptr<int> uniqPtr_1(new int(10));
unique_ptr<int> uniqPtr_2;

unique запрещает прямое присвоение другого умного указателя, для присвоения 2-м указателям ссылки на одим объект используется

uniqPtr_2=move(uniqPtr_1);
или
uniqPtr_2.swap(uniqPtr_1);

В обоих случаях ссылку будет иметь лишь последний уникальный указатель.
Данный тип указателя также имеет методы:

uniqPtr_1.reset();      //удалить указатель и данные
uniqPtr_1.release();  //удалить только указатель

shared_ptr (общий указатель):
Данный тип указателя используется наиболее часто, главная идея – сохранять данные о числе экземпляров умного указателя и удалять данные только когда число указателей на данную область памяти равно 0.

т.е. при создании

shared_ptr<int> sharedPtr_1(new int(10));
shared_ptr<int> sharedPtr_2(uniqPtr_1);

Умный указатель будет знать, что на переменную со значением “10” ссылаются 2 умных указателя, при вызове деструкторов счетчик будет уменьшаться, если счетчик дойдет до 0, то вызовется оператор delete или delete[].

Указатель на динамический массив:
чтобы сделать указатель на динамический массив в скобки шаблона <> надо поставить тип и скобки, например:
shared_ptr<int[]>sharedPtr(new int[2]{1,2});

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *