std::shared_ptr::reset
Материал из cppreference.com
< cpp | memory | shared ptr
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. Можно указать необязательное средство удаления d, которое позже используется для уничтожения нового объекта, когда им не владеет ни один объект shared_ptr
. По умолчанию в качестве средства удаления используется выражение delete. Всегда выбирается правильное выражение delete, соответствующее предоставленному типу, поэтому функция реализована в виде шаблона с использованием отдельного параметра Y
.
Если *this уже владеет объектом, и это последний shared_ptr
, владеющий им, объект уничтожается с помощью принадлежащего средства удаления.
Если объект, на который указывает ptr, уже принадлежит, функция обычно приводит к неопределённому поведению.
1) Освобождает владение управляемым объектом, если таковой имеется. После вызова *this не управляет никаким объектом. Эквивалентно shared_ptr().swap(*this);
2-4) Заменяет управляемый объект объектом, на который указывает ptr.
Y
должен быть полным типом и неявно преобразовываться в T
. Кроме того:2) Использует выражение delete в качестве средства удаления. Должно быть доступно действительное выражение delete, т.е. delete ptr должно быть корректно, иметь чётко определённое поведение и не вызывать никаких исключений. Эквивалентно shared_ptr<T>(ptr).swap(*this);.
3) Использует указанное средство удаления d в качестве средства удаления.
Deleter
должен вызываться для типа T
, т.е. d(ptr) должен быть корректным, иметь чётко определённое поведение и не вызывать никаких исключений. Deleter
должен быть CopyConstructible, а его конструктор копирования и деструктор не должны генерировать исключения. Эквивалентно shared_ptr<T>(ptr, d).swap(*this);.4) То же, что и (3), но дополнительно использует копию alloc для выделения данных для внутреннего использования.
Alloc
должен быть Allocator. Конструктор копирования и деструктор не должны генерировать исключения. Эквивалентно shared_ptr<T>(ptr, d, alloc).swap(*this);.Содержание |
[править]Параметры
ptr | — | указатель на объект, для которого нужно получить право собственности |
d | — | средство удаления для удаления объекта |
alloc | — | аллокатор, используемый для внутренних распределений |
[править]Возвращаемое значение
(нет)
[править]Исключения
2)std::bad_alloc, если требуемая дополнительная память не может быть получена. Может генерировать определяемое реализацией исключение для других ошибок. Вызывается delete ptr, если возникает исключение.
3,4)std::bad_alloc, если требуемая дополнительная память не может быть получена. Может генерировать определяемое реализацией исключение для других ошибок. Вызывается d(ptr), если возникает исключение.
[править]Пример
Запустить этот код
#include <memory>#include <iostream> 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()constnoexcept{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.reset();// здесь вызывает деструктор Foostd::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.reset(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.reset(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 (public функция-элемент) |