Namespaces
Variants

std::shared_ptr<T>:: reset

From cppreference.net
Memory management library
( exposition only* )
Allocators
Uninitialized memory algorithms
Constrained uninitialized memory algorithms
Memory resources
Uninitialized storage (until C++20)
( until C++20* )
( until C++20* )
( until C++20* )

Garbage collector support (until C++23)
(C++11) (until C++23)
(C++11) (until C++23)
(C++11) (until C++23)
(C++11) (until C++23)
(C++11) (until C++23)
(C++11) (until C++23)
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 уже принадлежит, функция обычно приводит к неопределённому поведению.

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) уникальное владение\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
(публичная функция-член)