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. Можно указать необязательный удалитель d, который впоследствии используется для уничтожения нового объекта, когда им не владеют никакие shared_ptr объекты. По умолчанию, в качестве удалителя используется выражение delete. Правильное выражение delete, соответствующее предоставленному типу, всегда выбирается, именно поэтому функция реализована как шаблон с использованием отдельного параметра Y.
Если *this уже владеет объектом, и это последний shared_ptr объект, владеющий им, то объект уничтожается с помощью удалителя, которым он владеет.
Если объект, на который указывает ptr уже принадлежит, то функция, как правило, приводит к неопределённому поведению.
*this не управляет никаким объектом. Эквивалентно shared_ptr().swap(*this);.ptr. Y должен быть полным типом и неявно преобразуемым в T. Кроме того:delete ptr должно быть корректным, иметь определённое поведение и не выбрасывать исключения. Эквивалентно shared_ptr<T>(ptr).swap(*this);.d в качестве удалителя. Deleter должен быть вызываемым для типа T, т. е. d(ptr) должно быть корректным, иметь определённое поведение и не выбрасывать исключения. Deleter должен быть CopyConstructible, а его конструктор копирования и деструктор не должны выбрасывать исключения. Эквивалентно shared_ptr<T>(ptr, d).swap(*this);.alloc для выделения памяти для внутренних целей. Alloc должен быть Allocator. Конструктор копирования и деструктор не должны выбрасывать исключения. Эквивалентно shared_ptr<T>(ptr, d, alloc).swap(*this);.Параметры
| ptr | - | указатель на объект, для которого необходимо получить владение |
| d | - | удалитель для хранения для удаления объекта |
| alloc | - | используемый выделенщик для внутренних выделений |
Возвращаемое значение
(ничего)
Исключения
std::bad_alloc если необходимая дополнительная память не может быть получена. Может сгенерировать реализационно-определенное исключение для других ошибок. delete ptr вызывается в случае возникновения исключения.std::bad_alloc если необходимая дополнительная память не может быть получена. Может сгенерировать реализационно-определенное исключение для других ошибок. d(ptr) вызывается в случае возникновения исключения.Пример
#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) unique ownership\n";
{
std::shared_ptr<Foo> sptr = std::make_shared<Foo>(100);
std::cout << "Foo::bar = " << sptr->getBar() << ", use_count() = "
<< sptr.use_count() << '\n';
// Reset the shared_ptr without handing it a fresh instance of Foo.
// The old instance will be destroyed after this call.
std::cout << "call sptr.reset()...\n";
sptr.reset(); // calls Foo's destructor here
std::cout << "After reset(): use_count() = " << sptr.use_count()
<< ", sptr = " << sptr << '\n';
} // No call to Foo's destructor, it was done earlier in reset().
std::cout << "\n2) unique ownership\n";
{
std::shared_ptr<Foo> sptr = std::make_shared<Foo>(200);
std::cout << "Foo::bar = " << sptr->getBar() << ", use_count() = "
<< sptr.use_count() << '\n';
// Reset the shared_ptr, hand it a fresh instance of Foo.
// The old instance will be destroyed after this call.
std::cout << "call sptr.reset()...\n";
sptr.reset(new Foo{222});
std::cout << "After reset(): use_count() = " << sptr.use_count()
<< ", sptr = " << sptr << "\nLeaving the scope...\n";
} // Calls Foo's destructor.
std::cout << "\n3) multiple ownership\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';
// Reset the shared_ptr sptr1, hand it a fresh instance of Foo.
// The old instance will stay shared between sptr2 and sptr3.
std::cout << "call sptr1.reset()...\n";
sptr1.reset(new Foo{333});
std::cout << "After 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'
<< "Leaving the scope...\n";
} // Calls two destructors of: 1) Foo owned by sptr1,
// 2) Foo shared between sptr2/sptr3.
}Возможный вывод:
1) unique ownership Foo::Foo(), bar = 100 @ 0x23c5040 Foo::bar = 100, use_count() = 1 call sptr.reset()... Foo::~Foo(), bar = 100 @ 0x23c5040 After reset(): use_count() = 0, sptr = 0 2) unique ownership Foo::Foo(), bar = 200 @ 0x23c5040 Foo::bar = 200, use_count() = 1 call sptr.reset()... Foo::Foo(), bar = 222 @ 0x23c5050 Foo::~Foo(), bar = 200 @ 0x23c5040 After reset(): use_count() = 1, sptr = 0x23c5050 Leaving the scope... Foo::~Foo(), bar = 222 @ 0x23c5050 3) multiple ownership Foo::Foo(), bar = 300 @ 0x23c5080 Foo::bar = 300, use_count() = 3 call sptr1.reset()... Foo::Foo(), bar = 333 @ 0x23c5050 After reset(): sptr1.use_count() = 1, sptr1 @ 0x23c5050 sptr2.use_count() = 2, sptr2 @ 0x23c5080 sptr3.use_count() = 2, sptr3 @ 0x23c5080 Leaving the scope... Foo::~Foo(), bar = 300 @ 0x23c5080 Foo::~Foo(), bar = 333 @ 0x23c5050
См. также
создаёт новый shared_ptr (публичный член-функция) |
© cppreference.com
Licensed under the Creative Commons Attribution-ShareAlike Unported License v3.0.
https://en.cppreference.com/w/cpp/memory/shared_ptr/reset