Smart pointer — это объект, работать с которым можно как с обычным указателем, но при этом, в отличии от последнего, он предоставляет некоторый дополнительный функционал (например, автоматическое освобождение закрепленной за указателем области памяти).
В новом стандарте появились следующие умные указатели: unique_ptr, shared_ptr и weak_ptr. Все они объявлены в заголовочном файле <memory>
.
Следующие примеры взяты из источника (http://archive.kalnytskyi.com/2011/11/02/smart-pointers-in-cpp11/)
Данный указатель передает право владения другому указателю, но делает это не так, как auto_ptr.
std::unique_ptr<int> x_ptr(new int(42));
std::unique_ptr<int> y_ptr;
// ошибка при компиляции
y_ptr = x_ptr;
// ошибка при компиляции
std::unique_ptr<int> z_ptr(x_ptr);
Правильно:
std::unique_ptr<int> x_ptr(new int(42));
std::unique_ptr<int> y_ptr;
// также, как и в случае с ``auto_ptr``, права владения переходят
// к y_ptr, а x_ptr начинает указывать на null pointer
y_ptr = std::move(x_ptr);
Полезные методы:
std::unique_ptr<Foo> ptr = std::unique_ptr<Foo>(new Foo);
// получаем классический указатель
Foo *foo = ptr.get();
foo->bar();
// сбрасываем права владения
ptr.reset();
С указателем связан счетчик ссылок. Если он обнуляется, то ресурс автоматически освобождается.
std::shared_ptr<int> x_ptr(new int(42));
std::shared_ptr<int> y_ptr(new int(13));
// после выполнения данной строчки, ресурс
// на который указывал ранее y_ptr (int(13)) освободится,
// а на int(42) будут ссылаться оба указателя
y_ptr = x_ptr;
std::cout << *x_ptr << "\t" << *y_ptr << std::endl;
// int(42) освободится лишь при уничтожении последнего ссылающегося
// на него указателя
Для работы с массивами надо использовать uniq_ptr
std::unique_ptr<Foo[]> arr(new Foo[2]);
arr[0].doSomething();