Пространства имён
Варианты
Действия

std::shared_ptr::reset

Материал из cppreference.com
< cpp‎ | memory‎ | shared ptr
 
 
Библиотека утилит
Языковая поддержка
Поддержка типов (базовые типы, RTTI)
Макросы тестирования функциональности библиотеки (C++20)    
Управление динамической памятью
Программные утилиты
Поддержка сопрограмм (C++20)
Вариативные функции
Трёхстороннее сравнение (C++20)
(C++20)
(C++20)(C++20)(C++20)(C++20)(C++20)(C++20)
Общие утилиты
Дата и время
Функциональные объекты
Библиотека форматирования (C++20)
(C++11)
Операторы отношения (устарело в C++20)
Целочисленные функции сравнения
(C++20)(C++20)(C++20)    
(C++20)
Операции обмена и типа
(C++14)
(C++11)
(C++11)
(C++11)
(C++17)
Общие лексические типы
(C++11)
(C++17)
(C++17)
(C++17)
(C++11)
(C++17)
(C++23)
Элементарные преобразования строк
(C++17)
(C++17)
 
Динамическое управление памятью
no section name
Ограниченные алгоритмы неинициализированной памяти
no section name
Поддержка сбора мусора
(C++11)(до C++23)
(C++11)(до C++23)
(C++11)(до C++23)
(C++11)(до C++23)
(C++11)(до C++23)
(C++11)(до C++23)



no section name
 
 
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() 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.reset(); // здесь вызывает деструктор 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.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 функция-элемент) [править]