在std::shared_ptr上使用.reset()会删除所有实例吗?

45

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

所以,既然我使用了重置函数,所有实例都从内存中删除了吗?也就是说,我刚刚用 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是在函数中创建但从未被清除吗?还是只有一个,并且当返回值时自动清理?


糟糕!如果您想提出后续问题,请使用页面顶部的“提问”按钮。简而言之,shared_ptr 的存在是为了自动处理所有这些事情,因此当最后一个共享指针离开作用域时,对象将被销毁。 - Dietrich Epp
等同于 shared_ptr().swap(*this); - Ayxan Haqverdili
3个回答

69

如果您使用.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

请注意,pq都是对象的所有者。一旦 pq 都被重置,那么 该实例就会被销毁。


1
谢谢您的回答!作为后续问题,假设我有一个返回类型为std::shared_ptr的函数,但是我返回的shared_ptr是在该函数内创建的,那么返回shared_ptr会自动将其use_count减1吗?我将在上面发布后续示例。 - zeus_masta_funk

18

整个shared_ptr的目的在于,如果有其他地方正在使用它,你就无法从一个地方删除它。 shared_ptr :: reset() 只是将use_count减一,并用nullptr替换其对象。


2

.reset()方法仅适用于调用它的对象。

它只是替换变量所持有的指针。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接