当前位置:首页 C++ > 正文

详细讲解C++中shared_ptr怎么知道跟它共享对象的指针释放了?

作者:野牛程序员:2023-05-18 16:43:04 C++阅读 2474

std::shared_ptr 是 C++ 中的一个智能指针,用于管理动态分配的对象资源。它使用引用计数来跟踪有多少个 std::shared_ptr 共享同一个对象,并在引用计数降为零时释放对象。

当最后一个 std::shared_ptr 对象销毁或重置时,它将检查引用计数。如果引用计数为零,说明没有其他 std::shared_ptr 对象共享该对象,因此它会释放对象并释放对象所占用的内存。

以下是 std::shared_ptr 如何知道何时释放共享对象的简要说明:

  1. std::shared_ptr 类中包含一个内部控制块(control block),通常称为引用计数块(reference count block)。该控制块维护一个引用计数和指向实际对象的指针。

  2. 当创建一个 std::shared_ptr 时,它会通过分配一个控制块来管理资源。控制块中的引用计数初始化为1,并将指向对象的指针保存在其中。

  3. 当你将一个 std::shared_ptr 对象复制给另一个 std::shared_ptr 对象时,引用计数会递增。

  4. std::shared_ptr 对象销毁或通过 reset() 函数重置时,引用计数会递减。

  5. 每次引用计数递减时,std::shared_ptr 会检查计数是否为零。如果计数为零,意味着没有其他 std::shared_ptr 对象共享该对象,因此它会释放对象并释放对象所占用的内存。

  6. 为了实现这种行为,std::shared_ptr 使用了析构函数和控制块。析构函数负责递减引用计数,而控制块负责追踪引用计数和释放对象。

总结来说,std::shared_ptr 在析构函数中检查引用计数是否为零,如果是,则释放共享对象。这是通过控制块内部的引用计数实现的,每当引用计数递减时,检查计数是否为零,并在需要时释放对象。

请注意,std::shared_ptr 还提供了其他功能,例如自定义删除器(deleter)、自定义分配器(allocator)等。但上述是它如何知道何时释放共享对象的基本原理。


以下是一个简单的代码演示,展示了如何使用 std::shared_ptr 并观察它如何知道何时释放共享对象:

#include <iostream>
#include <memory>

class MyClass {
public:
    MyClass() {
        std::cout << "MyClass constructor called" << std::endl;
    }

    ~MyClass() {
        std::cout << "MyClass destructor called" << std::endl;
    }
};

int main() {
    std::shared_ptr<MyClass> sharedPtr(new MyClass());
    std::cout << "sharedPtr use count: " << sharedPtr.use_count() << std::endl;

    {
        std::shared_ptr<MyClass> sharedPtr2 = sharedPtr;
        std::cout << "sharedPtr use count: " << sharedPtr.use_count() << std::endl;
    }

    std::cout << "sharedPtr use count: " << sharedPtr.use_count() << std::endl;

    return 0;
}

输出结果应为:

MyClass constructor called
sharedPtr use count: 1
sharedPtr use count: 2
sharedPtr use count: 1
MyClass destructor called

解释每个步骤:

  1. 在主函数中,我们创建了一个 std::shared_ptr 对象 sharedPtr,并通过 new 创建了一个 MyClass 对象,并将其分配给 sharedPtr

  2. 我们输出 sharedPtr 的引用计数,此时为 1。

  3. 在一个新的作用域内,我们创建了另一个 std::shared_ptr 对象 sharedPtr2,将其初始化为 sharedPtr。这导致引用计数增加到 2。

  4. 我们再次输出 sharedPtr 的引用计数,此时为 2。

  5. 离开内部作用域后,sharedPtr2 被销毁,引用计数递减到 1。

  6. 最后,我们输出 sharedPtr 的引用计数,此时为 1。

  7. 程序结束时,sharedPtr 超出作用域,sharedPtr 对象被销毁,引用计数递减到 0。因此,MyClass 的析构函数被调用,释放了共享的对象。

这个示例演示了 std::shared_ptr 如何通过引用计数来知道何时释放共享对象。


野牛程序员教少儿编程与信息学奥赛-微信|电话:15892516892
野牛程序员教少儿编程与信息学竞赛-微信|电话:15892516892
相关推荐

最新推荐

热门点击