Использует .reset() на std:: shared_ptr удаляет все экземпляры

Я новичок в shared_ptr, и я пытаюсь выяснить точную функциональность функции .reset().

#include <memory>
#include <stdio>

using namespace std;
class SomeClass{};

int main() 
{
   shared_ptr<SomeClass> sp (nullptr);

   //do some stuff, sp now has 10 co-owners

   cout << sp.use_count << endl;
   sp.reset();
   cout << sp.use_count << endl;
   return 0;
}

Выведет

10
0

Итак, поскольку я использовал функцию reset, все экземпляры удалены из памяти? Как и в, я только что устранил любые возможные утечки памяти с помощью sp? Очевидно, это был пример игрушек, который я быстро составил, извините, если у него есть какие-либо ошибки.

Последующая ситуация:

shared_ptr<SomeClass> returnThis() {
    shared_ptr<SomeClass> someObject(new SomeClass(/*default constructor for example*/) );
    return someObject;
}

в основном:

shared_ptr<SomeClass> mainObject;
mainObject = returnThis();

Имеет ли mainObject количество использования 2, потому что someObject был создан в функции, но не очищен? Или он один, и очистка выполняется автоматически при возврате значения?

Ответы

Ответ 1

Когда вы используете .reset(), вы удаляете одного владельца указателя, но все остальные владельцы все еще рядом. Вот пример:

#include <memory>
#include <cstdio>

class Test { public: ~Test() { std::puts("Test destroyed."); } };

int main()
{
    std::shared_ptr<Test> p = std::make_shared<Test>();
    std::shared_ptr<Test> q = p;
    std::puts("p.reset()...");
    p.reset();
    std::puts("q.reset()...");
    q.reset();
    std::puts("done");
    return 0;
}

Вывод программы:

p.reset()...
q.reset()...
Test destroyed.
done

Обратите внимание, что p и q являются владельцами объекта, и как только p и q reset, , то экземпляр уничтожается.

Ответ 2

Нет, вся цель shared_ptr заключается в том, что вы не можете удалить его из одного места, если кто-то использует его в другом. sp.reset() просто уменьшает значение use_count на единицу и заменяет его объект на nullptr.

Ответ 3

Метод .reset() применим только к объекту, на который он вызвал.

Он просто заменяет указатель, который удерживает переменная.