std::shared_ptr<T>:: reset
|
void
reset
(
)
noexcept
;
|
(1) | (начиная с C++11) |
|
template
<
class
Y
>
void reset ( Y * ptr ) ; |
(2) | (начиная с C++11) |
|
template
<
class
Y,
class
Deleter
>
void reset ( Y * ptr, Deleter d ) ; |
(3) | (начиная с C++11) |
|
template
<
class
Y,
class
Deleter,
class
Alloc
>
void reset ( Y * ptr, Deleter d, Alloc alloc ) ; |
(4) | (начиная с C++11) |
Заменяет управляемый объект на объект, на который указывает
ptr
. Может быть предоставлен опциональный deleter
d
, который позже используется для уничтожения нового объекта, когда ни один из объектов
shared_ptr
не владеет им. По умолчанию используется выражение
delete
. Всегда выбирается правильное выражение
delete
, соответствующее предоставленному типу, это причина, по которой функция реализована как шаблон с использованием отдельного параметра
Y
.
Если
*
this
уже владеет объектом и является последним
shared_ptr
, владеющим им, объект уничтожается с помощью сохраненного удалителя.
Если объект, на который указывает ptr уже принадлежит, функция обычно приводит к неопределённому поведению.
Y
должен быть полным типом и неявно преобразуемым в
T
. Дополнительно:
Deleter
должен быть вызываемым для типа
T
, т.е.
d
(
ptr
)
должен быть корректно сформирован, иметь определенное поведение и не генерировать исключений.
Deleter
должен быть
CopyConstructible
, и его конструктор копирования и деструктор не должны генерировать исключения. Эквивалентно
shared_ptr
<
T
>
(
ptr, d
)
.
swap
(
*
this
)
;
.
Alloc
должен быть
Allocator
. Конструктор копирования и деструктор не должны генерировать исключения. Эквивалентно
shared_ptr
<
T
>
(
ptr, d, alloc
)
.
swap
(
*
this
)
;
.
Содержание |
Параметры
| ptr | - | указатель на объект для получения владения |
| d | - | удалитель для хранения с целью удаления объекта |
| alloc | - | аллокатор для использования при внутренних выделениях памяти |
Возвращаемое значение
(нет)
Исключения
Пример
#include <iostream> #include <memory> struct Foo { Foo(int n = 0) noexcept : bar(n) { std::cout << "Foo::Foo(), bar = " << bar << " @ " << this << '\n'; } ~Foo() { std::cout << "Foo::~Foo(), bar = " << bar << " @ " << this << '\n'; } int getBar() const noexcept { return bar; } private: int bar; }; int main() { std::cout << "1) уникальное владение\n"; { std::shared_ptr<Foo> sptr = std::make_shared<Foo>(100); std::cout << "Foo::bar = " << sptr->getBar() << ", use_count() = " << sptr.use_count() << '\n'; // Сбросить shared_ptr без передачи ему нового экземпляра Foo. // Старый экземпляр будет уничтожен после этого вызова. std::cout << "вызвать sptr.reset()...\n"; sptr.сброс(); // вызов деструктора Foo здесь std::cout << "После reset(): use_count() = " << sptr.use_count() << ", sptr = " << sptr << '\n'; } // Вызов деструктора Foo не производится, он был выполнен ранее в reset(). std::cout << "\n2) уникальное владение\n"; { std::shared_ptr<Foo> sptr = std::make_shared<Foo>(200); std::cout << "Foo::bar = " << sptr->getBar() << ", use_count() = " << sptr.use_count() << '\n'; // Сбросить shared_ptr, передав ему новый экземпляр Foo. // Старый экземпляр будет уничтожен после этого вызова. std::cout << "вызвать sptr.reset()...\n"; sptr.сброс(new Foo{222}); std::cout << "После reset(): use_count() = " << sptr.use_count() << ", sptr = " << sptr << "\nВыход из области видимости...\n"; } // Вызывает деструктор Foo. std::cout << "\n3) множественное владение\n"; { std::shared_ptr<Foo> sptr1 = std::make_shared<Foo>(300); std::shared_ptr<Foo> sptr2 = sptr1; std::shared_ptr<Foo> sptr3 = sptr2; std::cout << "Foo::bar = " << sptr1->getBar() << ", use_count() = " << sptr1.use_count() << '\n'; // Сбросить shared_ptr sptr1, передать ему новый экземпляр Foo. // Старый экземпляр останется общим между sptr2 и sptr3. std::cout << "вызов sptr1.reset()...\n"; sptr1.сброс(new Foo{333}); std::cout << "После reset():\n" << "sptr1.use_count() = " << sptr1.use_count() << ", sptr1 @ " << sptr1 << '\n' << "sptr2.use_count() = " << sptr2.use_count() << ", sptr2 @ " << sptr2 << '\n' << "sptr3.use_count() = " << sptr3.use_count() << ", sptr3 @ " << sptr3 << '\n' << "Выход из области видимости...\n"; } // Вызывает два деструктора: 1) Foo, принадлежащего sptr1, // 2) Foo разделён между sptr2/sptr3. }
Возможный вывод:
1) уникальное владение Foo::Foo(), bar = 100 @ 0x23c5040 Foo::bar = 100, use_count() = 1 вызов sptr.reset()... Foo::~Foo(), bar = 100 @ 0x23c5040 После reset(): use_count() = 0, sptr = 0 2) уникальное владение Foo::Foo(), bar = 200 @ 0x23c5040 Foo::bar = 200, use_count() = 1 вызов sptr.reset()... Foo::Foo(), bar = 222 @ 0x23c5050 Foo::~Foo(), bar = 200 @ 0x23c5040 После reset(): use_count() = 1, sptr = 0x23c5050 Выход из области видимости... Foo::~Foo(), bar = 222 @ 0x23c5050 3) множественное владение Foo::Foo(), bar = 300 @ 0x23c5080 Foo::bar = 300, use_count() = 3 вызов sptr1.reset()... Foo::Foo(), bar = 333 @ 0x23c5050 После reset(): sptr1.use_count() = 1, sptr1 @ 0x23c5050 sptr2.use_count() = 2, sptr2 @ 0x23c5080 sptr3.use_count() = 2, sptr3 @ 0x23c5080 Выход из области видимости... Foo::~Foo(), bar = 300 @ 0x23c5080 Foo::~Foo(), bar = 333 @ 0x23c5050
Смотрите также
создает новый
shared_ptr
(публичная функция-член) |