Класс shared_ptr
Помещает объект с динамическим выделением памяти в оболочку интеллектуального указателя с подсчитанными ссылками.
Синтаксис
template <class T>
class shared_ptr;
Замечания
Класс shared_ptr
описывает объект, использующий подсчет ссылок для управления ресурсами. Объект shared_ptr
фактически содержит указатель на ресурс, которым он владеет, или содержит пустой указатель (NULL). Обладать ресурсом могут несколько объектов shared_ptr
; при удалении последнего объекта shared_ptr
, обладающего тем или иным ресурсом, данный ресурс освобождается.
При shared_ptr
переназначении или сбросе ресурса прекращается владение ресурсом.
Аргумент шаблона T
может быть неполным типом, за исключением случаев, особо отмеченных для определенных функций-членов.
При создании объекта shared_ptr<T>
из указателя ресурса типа G*
или из shared_ptr<G>
тип указателя G*
должен допускать преобразование в T*
. Если он не преобразуется, код не будет компилироваться. Например:
#include <memory>
using namespace std;
class F {};
class G : public F {};
shared_ptr<G> sp0(new G); // okay, template parameter G and argument G*
shared_ptr<G> sp1(sp0); // okay, template parameter G and argument shared_ptr<G>
shared_ptr<F> sp2(new G); // okay, G* convertible to F*
shared_ptr<F> sp3(sp0); // okay, template parameter F and argument shared_ptr<G>
shared_ptr<F> sp4(sp2); // okay, template parameter F and argument shared_ptr<F>
shared_ptr<int> sp5(new G); // error, G* not convertible to int*
shared_ptr<int> sp6(sp2); // error, template parameter int and argument shared_ptr<F>
Объект shared_ptr
владеет ресурсом:
если он был создан с использованием указателя на этот ресурс;
если он был создан из объекта
shared_ptr
, владеющего этим ресурсом;Значение
weak_ptr
/gt;, если оно было создано из объекта, указывающего на этот ресурс, илиЗначение
shared_ptr::operator=
помощью вызова функции-членаshared_ptr::reset
.
Владеющие ресурсом объекты shared_ptr
совместно используют один блок управления. Блок управления содержит следующее:
количество объектов
shared_ptr
, владеющих ресурсом;количество объектов
weak_ptr
, указывающих на ресурс;метод удаления для этого ресурса, если он есть;
пользовательский распределитель для блока управления, если он есть.
Объект shared_ptr
, инициализированный с помощью указателя NULL, имеет блок управления и не пуст. После того как объект shared_ptr
освобождает ресурс, он перестает быть его владельцем. После того как объект weak_ptr
освобождает ресурс, он перестает указывать на него.
Если количество объектов shared_ptr
, владеющих ресурсом, становится равным нулю, ресурс освобождается путем удаления или передачи его адреса в метод удаления в зависимости от того, как изначально был создан владелец ресурса. Если количество объектов shared_ptr
, владеющих ресурсом, как и число объектов weak_ptr
, которые указывают на ресурс, становится равным нулю, освобождается блок управления с использованием пользовательского распределителя этого блока управления при его наличии.
Пустой shared_ptr
объект не владеет ресурсами и не имеет блока управления.
Метод удаления является объектом функции, имеющим функцию-член operator()
. Его тип должен быть конструируемым по копии, а его конструктор копии и деструктор не должны выдавать исключения. Он принимает один параметр — удаляемый объект.
Некоторые функции принимают список аргументов, определяющий свойства результирующего объекта shared_ptr<T>
или weak_ptr<T>
. Такой список аргументов можно задать несколькими способами.
нет аргументов: результирующий объект является пустым shared_ptr
объектом или пустым weak_ptr
объектом.
ptr
: указатель типа Other*
на управляемый ресурс. T
должен быть полным типом. Если функция завершается ошибкой (так как блок управления не может быть выделен), она вычисляет выражение delete ptr
.
ptr, deleter
: указатель типа Other*
на управляемый ресурс и средство удаления для этого ресурса. Если функция завершается сбоем (так как блок управления не может быть выделен), он вызывает deleter(ptr)
вызовы, которые должны быть четко определены.
ptr, deleter, alloc
: указатель типа Other*
на управляемый ресурс, удаленный для этого ресурса и распределитель для управления любым хранилищем, которое должно быть выделено и освобождено. Если функция завершается сбоем (так как блок управления не может быть выделен), он вызывает deleter(ptr)
вызовы, которые должны быть четко определены.
sp
shared_ptr<Other>
: объект, принадлежащий управляемому ресурсу.
wp
: объект, указывающий weak_ptr<Other>
на управляемый ресурс.
ap
auto_ptr<Other>
: объект, содержащий указатель на управляемый ресурс. Если функция выполнена успешно, она вызывается ap.release()
; в противном случае она остается ap
без изменений.
Во всех случаях тип указателя типа Other*
должен допускать преобразование в T*
.
Потокобезопасность
Несколько потоков могут одновременно считывать и записывать разные объекты shared_ptr
, даже если они являются копиями с общим владельцем.
Участники
Имя | Описание |
---|---|
Конструкторы | |
shared_ptr |
Создает документ shared_ptr . |
~shared_ptr |
Удаляет shared_ptr . |
Typedefs | |
element_type |
Тип элемента. |
weak_type |
Тип слабого указателя на элемент. |
Функции-члены | |
get |
Возвращает адрес принадлежащего ресурса. |
owner_before |
Возвращает значение true, если shared_ptr упорядочен до (меньше) предоставленного указателя. |
reset |
Заменяет принадлежащий ресурс. |
swap |
Меняет местами два объекта shared_ptr . |
unique |
Проверяет, является ли принадлежащий ресурс уникальным. |
use_count |
Подсчитывает количество владельцев ресурса. |
Операторы | |
operator bool |
Проверяет существование принадлежащего ресурса. |
operator* |
Возвращает указанное значение. |
operator= |
Заменяет принадлежащий ресурс. |
operator-> |
Получает указатель на указанное значение. |
element_type
Тип элемента.
typedef T element_type; // before C++17
using element_type = remove_extent_t<T>; // C++17
Замечания
Тип element_type
является синонимом для параметра T
шаблона.
Пример
// std__memory__shared_ptr_element_type.cpp
// compile with: /EHsc
#include <memory>
#include <iostream>
int main()
{
std::shared_ptr<int> sp0(new int(5));
std::shared_ptr<int>::element_type val = *sp0;
std::cout << "*sp0 == " << val << std::endl;
return (0);
}
*sp0 == 5
get
Возвращает адрес принадлежащего ресурса.
element_type* get() const noexcept;
Замечания
Функция-член возвращает адрес контролируемого ресурса. Если объект не владеет ресурсом, он возвращает значение 0.
Пример
// std__memory__shared_ptr_get.cpp
// compile with: /EHsc
#include <memory>
#include <iostream>
int main()
{
std::shared_ptr<int> sp0;
std::shared_ptr<int> sp1(new int(5));
std::cout << "sp0.get() == 0 == " << std::boolalpha
<< (sp0.get() == 0) << std::endl;
std::cout << "*sp1.get() == " << *sp1.get() << std::endl;
return (0);
}
sp0.get() == 0 == true
*sp1.get() == 5
operator bool
Проверяет существование принадлежащего ресурса.
explicit operator bool() const noexcept;
Замечания
Оператор возвращает значение true
, в get() != nullptr
противном случае false
.
Пример
// std__memory__shared_ptr_operator_bool.cpp
// compile with: /EHsc
#include <memory>
#include <iostream>
int main()
{
std::shared_ptr<int> sp0;
std::shared_ptr<int> sp1(new int(5));
std::cout << "(bool)sp0 == " << std::boolalpha
<< (bool)sp0 << std::endl;
std::cout << "(bool)sp1 == " << std::boolalpha
<< (bool)sp1 << std::endl;
return (0);
}
(bool)sp0 == false
(bool)sp1 == true
operator*
Возвращает указанное значение.
T& operator*() const noexcept;
Замечания
Оператор косвенного обращения возвращает *get()
. Следовательно, сохраненный указатель не должен быть пустым.
Пример
// std__memory__shared_ptr_operator_st.cpp
// compile with: /EHsc
#include <memory>
#include <iostream>
int main()
{
std::shared_ptr<int> sp0(new int(5));
std::cout << "*sp0 == " << *sp0 << std::endl;
return (0);
}
*sp0 == 5
operator=
Заменяет принадлежащий ресурс.
shared_ptr& operator=(const shared_ptr& sp) noexcept;
shared_ptr& operator=(shared_ptr&& sp) noexcept;
template <class Other>
shared_ptr& operator=(const shared_ptr<Other>& sp) noexcept;
template <class Other>
shared_ptr& operator=(shared_ptr<Other>&& sp) noexcept;
template <class Other>
shared_ptr& operator=(auto_ptr<Other>&& ap); // deprecated in C++11, removed in C++17
template <class Other, class Deleter>
shared_ptr& operator=(unique_ptr<Other, Deleter>&& up);
Параметры
sp
Общий указатель для копирования или перемещения.
ap
Автоматический указатель для перемещения. Перегрузка auto_ptr
устарела в C++11 и удалена в C++17.
up
Уникальный указатель на объект для принятия права владения. up
не владеет объектом после вызова.
Other
Тип объекта, на который указывает sp
, ap
или up
.
Deleter
Тип удаленного объекта, хранящегося для последующего удаления объекта.
Замечания
Все операторы уменьшают значение счетчика ссылок для ресурса, который в настоящее время контролируется *this
, и передают владение ресурсом, указанным последовательностью операндов, объекту *this
. Если число ссылок на ресурс становится равным нулю, ресурс освобождается (delete). Если оператор завершается ошибкой, он остается *this
неизменным.
Пример
// std__memory__shared_ptr_operator_as.cpp
// compile with: /EHsc
#include <memory>
#include <iostream>
int main()
{
std::shared_ptr<int> sp0;
std::shared_ptr<int> sp1(new int(5));
std::unique_ptr<int> up(new int(10));
sp0 = sp1;
std::cout << "*sp0 == " << *sp0 << std::endl;
sp0 = up;
std::cout << "*sp0 == " << *sp0 << std::endl;
return (0);
}
*sp0 == 5
*sp0 == 10
operator->
Получает указатель на указанное значение.
T* operator->() const noexcept;
Замечания
Оператор выбора возвращает get()
, так что выражение sp->member
ведет себя так же, как (sp.get())->member
, где sp
— это объект класса shared_ptr<T>
. Следовательно, сохраненный указатель не должен быть пустым, и T
должен быть классом, структурой или типом объединения с членом member
.
Пример
// std__memory__shared_ptr_operator_ar.cpp
// compile with: /EHsc
#include <memory>
#include <iostream>
typedef std::pair<int, int> Mypair;
int main()
{
std::shared_ptr<Mypair> sp0(new Mypair(1, 2));
std::cout << "sp0->first == " << sp0->first << std::endl;
std::cout << "sp0->second == " << sp0->second << std::endl;
return (0);
}
sp0->first == 1
sp0->second == 2
owner_before
Возвращает значение true, если shared_ptr
упорядочен до (меньше) предоставленного указателя.
template <class Other>
bool owner_before(const shared_ptr<Other>& ptr) const noexcept;
template <class Other>
bool owner_before(const weak_ptr<Other>& ptr) const noexcept;
Параметры
ptr
Ссылка на lvalue либо a shared_ptr
, либо a weak_ptr
.
Замечания
Функция-член шаблона возвращает значение true, если *this
он упорядочен до ptr
.
reset
Заменяет принадлежащий ресурс.
void reset() noexcept;
template <class Other>
void reset(Other *ptr);
template <class Other, class Deleter>
void reset(
Other *ptr,
Deleter deleter);
template <class Other, class Deleter, class Allocator>
void reset(
Other *ptr,
Deleter deleter,
Allocator alloc);
Параметры
Other
Тип, управляемый указателем аргумента.
Deleter
Тип метода удаления.
ptr
Копируемый указатель.
deleter
Метод удаления для копирования.
Allocator
Тип распределителя.
alloc
Распределитель для копирования.
Замечания
Все операторы уменьшают значение счетчика ссылок для ресурса, который в настоящее время контролируется *this
, и передают владение ресурсом, указанным последовательностью операндов, объекту *this
. Если число ссылок на ресурс становится равным нулю, ресурс освобождается (delete). Если оператор завершается ошибкой, он остается *this
неизменным.
Пример
// std__memory__shared_ptr_reset.cpp
// compile with: /EHsc
#include <memory>
#include <iostream>
struct deleter
{
void operator()(int *p)
{
delete p;
}
};
int main()
{
std::shared_ptr<int> sp(new int(5));
std::cout << "*sp == " << std::boolalpha
<< *sp << std::endl;
sp.reset();
std::cout << "(bool)sp == " << std::boolalpha
<< (bool)sp << std::endl;
sp.reset(new int(10));
std::cout << "*sp == " << std::boolalpha
<< *sp << std::endl;
sp.reset(new int(15), deleter());
std::cout << "*sp == " << std::boolalpha
<< *sp << std::endl;
return (0);
}
*sp == 5
(bool)sp == false
*sp == 10
*sp == 15
shared_ptr
Создает документ shared_ptr
.
constexpr shared_ptr() noexcept;
constexpr shared_ptr(nullptr_t) noexcept : shared_ptr() {}
shared_ptr(const shared_ptr& sp) noexcept;
shared_ptr(shared_ptr&& sp) noexcept;
template <class Other>
explicit shared_ptr(Other* ptr);
template <class Other, class Deleter>
shared_ptr(
Other* ptr,
Deleter deleter);
template <class Deleter>
shared_ptr(
nullptr_t ptr,
Deleter deleter);
template <class Other, class Deleter, class Allocator>
shared_ptr(
Other* ptr,
Deleter deleter,
Allocator alloc);
template <class Deleter, class Allocator>
shared_ptr(
nullptr_t ptr,
Deleter deleter,
Allocator alloc);
template <class Other>
shared_ptr(
const shared_ptr<Other>& sp) noexcept;
template <class Other>
explicit shared_ptr(
const weak_ptr<Other>& wp);
template <class &>
shared_ptr(
std::auto_ptr<Other>& ap);
template <class &>
shared_ptr(
std::auto_ptr<Other>&& ap);
template <class Other, class Deleter>
shared_ptr(
unique_ptr<Other, Deleter>&& up);
template <class Other>
shared_ptr(
const shared_ptr<Other>& sp,
element_type* ptr) noexcept;
template <class Other>
shared_ptr(
shared_ptr<Other>&& sp,
element_type* ptr) noexcept;
template <class Other, class Deleter>
shared_ptr(
const unique_ptr<Other, Deleter>& up) = delete;
Параметры
Other
Тип, управляемый указателем аргумента.
ptr
Копируемый указатель.
Deleter
Тип метода удаления.
Allocator
Тип распределителя.
deleter
Метод удаления.
alloc
Распределитель.
sp
Интеллектуальный указатель для копирования
wp
Слабый указатель.
ap
"Автоматический" указатель ( auto_ptr ) для копирования
Замечания
Каждый из конструкторов создает объект для контроля над ресурсом, указанным в качестве операнда. Конструктор shared_ptr(const weak_ptr<Other>& wp)
создает объект исключения типа bad_weak_ptr
, если wp.expired()
.
Пример
// std__memory__shared_ptr_construct.cpp
// compile with: /EHsc
#include <memory>
#include <iostream>
struct deleter
{
void operator()(int *p)
{
delete p;
}
};
int main()
{
std::shared_ptr<int> sp0;
std::cout << "(bool)sp0 == " << std::boolalpha
<< (bool)sp0 << std::endl;
std::shared_ptr<int> sp1(new int(5));
std::cout << "*sp1 == " << *sp1 << std::endl;
std::shared_ptr<int> sp2(new int(10), deleter());
std::cout << "*sp2 == " << *sp2 << std::endl;
std::shared_ptr<int> sp3(sp2);
std::cout << "*sp3 == " << *sp3 << std::endl;
std::weak_ptr<int> wp(sp3);
std::shared_ptr<int> sp4(wp);
std::cout << "*sp4 == " << *sp4 << std::endl;
std::auto_ptr<int> ap(new int(15));
std::shared_ptr<int> sp5(ap);
std::cout << "*sp5 == " << *sp5 << std::endl;
return (0);
}
(bool)sp0 == false
*sp1 == 5
*sp2 == 10
*sp3 == 10
*sp4 == 10
*sp5 == 15
~shared_ptr
Удаляет shared_ptr
.
~shared_ptr();
Замечания
Деструктор уменьшает значение счетчика ссылок для ресурса, который в настоящее время контролируется *this
. Если число ссылок на ресурс становится равным нулю, ресурс освобождается (delete).
Пример
// std__memory__shared_ptr_destroy.cpp
// compile with: /EHsc
#include <memory>
#include <iostream>
int main()
{
std::shared_ptr<int> sp1(new int(5));
std::cout << "*sp1 == " << *sp1 << std::endl;
std::cout << "use count == " << sp1.use_count() << std::endl;
{
std::shared_ptr<int> sp2(sp1);
std::cout << "*sp2 == " << *sp2 << std::endl;
std::cout << "use count == " << sp1.use_count() << std::endl;
}
// check use count after sp2 is destroyed
std::cout << "use count == " << sp1.use_count() << std::endl;
return (0);
}
*sp1 == 5
use count == 1
*sp2 == 5
use count == 2
use count == 1
swap
Меняет местами два объекта shared_ptr
.
void swap(shared_ptr& sp) noexcept;
Параметры
sp
Разделяемый указатель (shared_ptr), с которым требуется произвести обмен контролируемыми объектами.
Замечания
Функция-член устанавливает контроль sp
над ресурсом, изначально контролируемым *this
и контроль sp
над ресурсом, изначально контролируемым *this
. Функция не изменяет количество ссылок для двух ресурсов и не создает никаких исключений.
Пример
// std__memory__shared_ptr_swap.cpp
// compile with: /EHsc
#include <memory>
#include <iostream>
int main()
{
std::shared_ptr<int> sp1(new int(5));
std::shared_ptr<int> sp2(new int(10));
std::cout << "*sp1 == " << *sp1 << std::endl;
sp1.swap(sp2);
std::cout << "*sp1 == " << *sp1 << std::endl;
swap(sp1, sp2);
std::cout << "*sp1 == " << *sp1 << std::endl;
std::cout << std::endl;
std::weak_ptr<int> wp1(sp1);
std::weak_ptr<int> wp2(sp2);
std::cout << "*wp1 == " << *wp1.lock() << std::endl;
wp1.swap(wp2);
std::cout << "*wp1 == " << *wp1.lock() << std::endl;
swap(wp1, wp2);
std::cout << "*wp1 == " << *wp1.lock() << std::endl;
return (0);
}
*sp1 == 5
*sp1 == 10
*sp1 == 5
*wp1 == 5
*wp1 == 10
*wp1 == 5
unique
Проверяет, является ли принадлежащий ресурс уникальным. Эта функция устарела в C++17 и удалена в C++20.
bool unique() const noexcept;
Замечания
Функция-член возвращает значение true
, если никакой другой объект shared_ptr
не контролирует ресурс, контролируемый *this
; в противном случае — значение false
.
Пример
// std__memory__shared_ptr_unique.cpp
// compile with: /EHsc
#include <memory>
#include <iostream>
int main()
{
std::shared_ptr<int> sp1(new int(5));
std::cout << "sp1.unique() == " << std::boolalpha
<< sp1.unique() << std::endl;
std::shared_ptr<int> sp2(sp1);
std::cout << "sp1.unique() == " << std::boolalpha
<< sp1.unique() << std::endl;
return (0);
}
sp1.unique() == true
sp1.unique() == false
use_count
Подсчитывает количество владельцев ресурса.
long use_count() const noexcept;
Замечания
Функция-член возвращает число объектов shared_ptr
, контролирующих ресурс, который контролируется *this
.
Пример
// std__memory__shared_ptr_use_count.cpp
// compile with: /EHsc
#include <memory>
#include <iostream>
int main()
{
std::shared_ptr<int> sp1(new int(5));
std::cout << "sp1.use_count() == "
<< sp1.use_count() << std::endl;
std::shared_ptr<int> sp2(sp1);
std::cout << "sp1.use_count() == "
<< sp1.use_count() << std::endl;
return (0);
}
sp1.use_count() == 1
sp1.use_count() == 2
weak_type
Тип слабого указателя на элемент.
using weak_type = weak_ptr<T>; // C++17
Замечания
Определение weak_type
было добавлено в C++17.
См. также
Справочник по файлам заголовков
<memory>
unique_ptr
Класс weak_ptr