Spec-Zone.ru › C++

std::shared_ptr<T>::reset

void reset() noexcept;
(1) (начиная с C++11)
(constexpr начиная с C++26)
template< class Y > 
void reset( Y* ptr );
(2) (начиная с C++11)
(constexpr начиная с C++26)
template< class Y, class Deleter > 
void reset( Y* ptr, Deleter d );
(3) (начиная с C++11)
(constexpr начиная с C++26)
template< class Y, class Deleter, class Alloc > 
void reset( Y* ptr, Deleter d, Alloc alloc );
(4) (начиная с C++11)
(constexpr начиная с C++26)

Заменяет управляемый объект объектом, на который указывает ptr. Можно указать необязательный удалитель d, который впоследствии будет использоваться для уничтожения нового объекта, когда им не будет владеть ни один объект shared_ptr.

Если *this уже владеет объектом и является последним объектом shared_ptr, владеющим им, объект уничтожается с помощью принадлежащего ему удалителя.

1) Освобождает владение управляемым объектом (если он есть). После вызова *this не управляет никаким объектом.
Эквивалентно shared_ptr<T>().swap(*this);.
2-4) Заменяет управляемый объект объектом, на который указывает ptr.
2) В качестве удалителя используется выражение delete.
Эквивалентно shared_ptr<T>(ptr).swap(*this);.
3) В качестве удалителя используется указанный удалитель d.
Эквивалентно shared_ptr<T>(ptr, d).swap(*this);.
4) Аналогично (3), но дополнительно для выделения памяти под данные, используемые внутри, применяется копия alloc.
Эквивалентно shared_ptr<T>(ptr, d, alloc).swap(*this);.

Параметры

ptr - указатель на объект, которым нужно получить возможность владеть
d - удалитель, сохраняемый для удаления объекта
alloc - аллокатор для внутренних выделений памяти

Примечания

Всегда выбирается подходящее выражение delete, соответствующее указанному типу. Именно поэтому функция реализована как шаблон с использованием отдельного параметра Y.

Чтобы поведение конструктора shared_ptr, вызываемого внутри функции, было корректно определено, необходимо также выполнить те же условия. Например, если объект, на который указывает ptr, уже принадлежит другому объекту shared_ptr, вызов функции обычно приводит к неопределённому поведению.

Исключения

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/cpp/memory/shared_ptr/reset

Spec-Zone.ru

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