讲自己作为sharedptr传出_如果一个资源将被多层传递和访问,那么参数类型该用 weak_ptr 还是 shared_ptr?...

问题关键,并不是采用 shared_ptr 还是 weak_ptr,而是如何组织对象的生命周期管理。

从生命周期的管理上,shared_ptr 相当于做了一个 ReadLockGuard。在这个 Guard 析构之前,这个对象就一定是可用的,不会被 Free。也就保证了,在 Guard 范围内,能任意地使用 shared_ptr.get() 出来的指针。

但是,既然是 Lock,就需要控制 Lock 的范围。如果一直持有,就等于资源泄露;如果持有时间过长,会造成资源占用过久,浪费资源。更严重的是,如果有功能依赖对象析构,这个功能的执行可能阻塞过久。

weak_ptr 的作用,是用于辅助控制这个 Lock 的范围,让你有办法减少 Lock 的持有时间和范围。例如,下面一个简单的例子:

void long_hold(const shared_ptr& obj) {

shared_ptr holder = obj;

while(true) {

holder.DoSomething();

sleep(1);

}

}

void short_hold(const shard_ptr& obj) {

weak_ptr weak_holder = obj;

while(true) {

{

auto tmp_holder = weak_holder.lock();

if (!tmp_holder) break;

tmp_holder->DoSomething();

}

sleep(1);

}

}

上面实现了两个函数,long_hold () 在栈上持有了一个 shared_ptr,Lock 的范围是整个 long_hold 函数。在 long_hold 返回之前,对象不可能 Free。

short_hold() 在栈上持有的是 weakptr,这里并不会创建 Lock。而是等到 while 循环中不停地临时 Lock,使用完毕后立即释放。注意,与 long_hold 不同的是,这个 Lock 范围并不包含 sleep。那么,在 sleep 期间,外部的资源持有者就有机会执行 Free。

铺垫了这么多,下面说说我认为的一种适用范围广的实践姿势:参数类型使用 const shared_ptr & 或 A *。如果函数内可能传递共享权,用 const shared_ptr &;否则,用 A *;

必须在一个外部 shared_ptr (通常是在栈上)的保护下,传递 A* 或 const shared_ptr & 给函数做参数;

在调用函数中,根据目的,构造出 weak_ptr 或 shared_ptr 来传递共享权。

这样实践,一是,性能惩罚小,只在必需时构造 weak_ptr 和 shared_ptr;二是,参数类型能表明函数是否可能泄露共享权。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值