Spec-Zone.ru › C++

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 уже принадлежит, то функция, как правило, приводит к неопределённому поведению.

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 <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

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API