std::shared_ptr的巧妙应用

1 篇文章 0 订阅
1 篇文章 0 订阅

std::shared_ptr

一次创建,多处共享,通过引用计数控制生命周期。

问题:

假设有一项任务Task,其分为N个小模块,每个小模块都是并发执行。

现在要求,任务开始,每个小模块并发执行,在全部小模块执行完后,将所有小模块结果进行下一步处理,任务结束。

方案一:

任务开始,先创建一个成员变量std::set<Span*> n_span;(这里Span代表一个小模块,异步执行模块的功能);

将每个小模块都记录在n_span中;

当小模块执行完后,从n_span中移除;

当n_span为空时,意味着所有小模块都执行完毕,可以继续下一步处理了。

方案一看起来简单清晰,那么其存在什么问题呢?

假如某个小模块因为某种原因被销毁了,那么,其模块便不会返回,Task就会永远lost,永远不会继续下一步处理了。

*****std::shared_ptr闪亮登场*****

在使用std::shared_ptr时,我们很少注意到,其构造函数有两个参数,

第一个是对象指针,

第二个是deleter,可以让我们自己定义其析构函数。

auto next = [](){};
std::shared_ptr<void> shared_count((void*)0, [next](void*){ next() });
for(int i = 0; i < N; i++){
    Span* s = new Span(shared_count);
    s->Run();  // Span在执行结束后delete this
}
无论Span是正常还是非正常结束,保存在Span中的std::shared_ptr<void>销毁后都会导致shared_count引用计数-1,当引用计数为0时,其执行了我们定义的deleter,在此可以执行我们的下一步处理了。

`std::shared_ptr` 是 C++ 标准库中一个用于实现共享所有权的智能指针。它能够自动管理内存,当没有更多的 `std::shared_ptr` 指向同一个资源时,它会自动释放资源。`std::shared_ptr` 内部通过引用计数来跟踪有多少个 `std::shared_ptr` 实例共享同一个对象,当引用计数降为零时,对象会被删除。 以下是如何使用 `std::shared_ptr` 的基本步骤: 1. 包含头文件:使用 `std::shared_ptr` 需要包含 `<memory>` 头文件。 ```cpp #include <memory> ``` 2. 创建 `std::shared_ptr` 对象:可以使用 `std::make_shared` 或者直接使用 `new` 关键字配合 `std::shared_ptr` 构造函数创建。 ```cpp // 使用 std::make_shared std::shared_ptr<int> ptr1 = std::make_shared<int>(10); // 使用 new 关键字创建 std::shared_ptr<int> ptr2(new int(20)); ``` 3. 使用 `std::shared_ptr`:你可以像使用普通指针一样使用 `std::shared_ptr`,包括访问成员和解引用操作。 ```cpp *ptr1 = 30; // 通过指针修改值 int value = *ptr2; // 通过指针访问值 ``` 4. 通过拷贝或者赋值操作来增加引用计数:当你拷贝一个 `std::shared_ptr` 或者将一个 `std::shared_ptr` 赋值给另一个时,引用计数会增加。 ```cpp std::shared_ptr<int> ptr3 = ptr1; // 增加引用计数 ptr2 = ptr1; // 同样增加引用计数 ``` 5. 当 `std::shared_ptr` 对象被销毁时,它所管理的资源也会被自动释放。当最后一个 `std::shared_ptr` 被销毁或者被重置时,资源会被释放。 ```cpp ptr1.reset(); // 减少引用计数,若引用计数为零则释放资源 ``` 6. 可以检查引用计数:通过 `use_count()` 方法可以获取当前有多少个 `std::shared_ptr` 对象指向同一个资源。 ```cpp int count = ptr2.use_count(); ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值