boost::weak_ptr和enable_shared_from_this
2011-05-27 14:37
288 查看
boost::weak_ptr
和
enable_shared_from_this
shared_ptr
在我的实践中使用很广
,
在接口层面上
,
我基本都会默认的使用
shared_ptr.
而
weak_ptr
则很少使用
;
即便使用
,
也是间接的使用
,
例如使得
class A
继承自
boost::enable_shared_from_this,
这样
A
便具有了一个
weak_ptr
的成员对象
,
我便可以通过接口
shared_from_this()
得到一个
boost::shared_ptr<A>
的对象
.
除此之外
,
在实践中我几乎没有用到
weak_ptr.
到目前为止
,
我见到的对
weak_ptr
论述最好的是
<<
Beyond.the.C.plus.plus.Standard.Library.An.Introduction.to.Boost>>.
本书给出了使用
weak_ptr
的三种场景
:
打破递归的依赖关系
;
使用一个共享的资源而不需要共享所有权
;
避免悬空的指针
.
后面两种场景相对比较容易明白
,
对于第一种则相对模糊
.
最近几天我相对仔细的研究了一下
shared_ptr
和
weak_ptr
的源代码
,
给出我自己的理解如下
.
weak_ptr
是依附于
shared_ptr
的
,
所以首先要把
shared_ptr
弄清楚
;
另外
,
我认为
boost::enable_shared_from_this
是解释递归的依赖关系的最好例子
,
所以使用这个实例解释
weak_ptr
最好不过了
.
shared_ptr
的图解
如图所示
,3
个智能指针对象
sp1,sp2,sp3,
共享同一个对象
object
和同一个计数器
counter,
当
3
个指针对象
sp1,sp2,sp3
声明周期结束的时候
,counter==0,object
会被销毁
(
当然
,
这个销毁器本身可以由你定制
).
shared_ptr
的一个很大的特点是
:counter==0,object
会被销毁
;
反之
,
如果
counter
总是不为
0,
那么
object
会成为永久对象
,
例如全局对象
.
在
http://www.boost.org/doc/libs/1_35_0/libs/smart_ptr/sp_techniques.html
中给出了一个从
this
获得
shared_ptr
的实例
,
答案是使用
weak_ptr,
问题是为什么是
weak_ptr.
让我们把这个问题重新说明一下
:
struct X
{
boost::shared_ptr<X>
getX()
{
boost::shared_ptr<X>
r ;//????
如何实现
return r;
}
};
要得到
X
的智能指针
,
只是在对象指针是受
shared_ptr
保护的基础上的
,
举例如下
:
void test_X()
{
{
X x;
boost::shared_ptr<X> px =
x.getX();//
错误
}
{
X* x = new X();
boost::shared_ptr<X> px = x->getX();//
错误
}
{
boost::shared_ptr<X>
x (new X());
boost::shared_ptr<X> px = x->getX();//
正确
}
}
我们再回到原来的问题上
,
如何实现
X::getX()
函数
.
要构造
X
的智能指针
,
需要知道两个信息
,object
的指针和
object
的计数器
,
显然
,
指针本身可以通过
this
获得
,
问题是如何获得计数器
,
也即上面图中的
counter.
很显然
,
我们必须在
X
上存储某些信息来得到计数器
.
最先想到的也许是使用一个指向
counter
的指针存储在
X
上面
,
这样应该是可以的
,
但是存在一个问题
:
暴露了
shared_ptr
的实现细节
,
虽然
shared_ptr
是基于计数器的
,
但是这不属于用户需要知道的事情
.
最好的方式是让
shared_ptr
本身来充当这个角色
,
这样所有的实现细节就都封装在
shared_ptr
内部了
.
经过这样改装的
shared_ptr
的图解是
:
经过这样包装的
object,
问题立刻暴露出来
:
循环引用
,
造成
object
对象无法释放
,
成为
”
全局对象
”.
很显然
,
问题在于
object
本身参与了引用计数
,
也就是所有权的分享
.
我们需要的是不同于
shared_ptr
的这样的一类共享指针
:
他们并不参与对象的所有权
,
只是能够观察到对象的所有权
.
而这正是
weak_ptr
的本质所在
.
当然了
,weak_ptr
还有其他的特征
:
查看对象指针是否过期
(
这也是比裸指针好的地方
).
循环引用的情况很罕见
,
这可能也是我在实际中很少使用
weak_ptr
的原因吧
.
和
enable_shared_from_this
shared_ptr
在我的实践中使用很广
,
在接口层面上
,
我基本都会默认的使用
shared_ptr.
而
weak_ptr
则很少使用
;
即便使用
,
也是间接的使用
,
例如使得
class A
继承自
boost::enable_shared_from_this,
这样
A
便具有了一个
weak_ptr
的成员对象
,
我便可以通过接口
shared_from_this()
得到一个
boost::shared_ptr<A>
的对象
.
除此之外
,
在实践中我几乎没有用到
weak_ptr.
到目前为止
,
我见到的对
weak_ptr
论述最好的是
<<
Beyond.the.C.plus.plus.Standard.Library.An.Introduction.to.Boost>>.
本书给出了使用
weak_ptr
的三种场景
:
打破递归的依赖关系
;
使用一个共享的资源而不需要共享所有权
;
避免悬空的指针
.
后面两种场景相对比较容易明白
,
对于第一种则相对模糊
.
最近几天我相对仔细的研究了一下
shared_ptr
和
weak_ptr
的源代码
,
给出我自己的理解如下
.
weak_ptr
是依附于
shared_ptr
的
,
所以首先要把
shared_ptr
弄清楚
;
另外
,
我认为
boost::enable_shared_from_this
是解释递归的依赖关系的最好例子
,
所以使用这个实例解释
weak_ptr
最好不过了
.
shared_ptr
的图解
如图所示
,3
个智能指针对象
sp1,sp2,sp3,
共享同一个对象
object
和同一个计数器
counter,
当
3
个指针对象
sp1,sp2,sp3
声明周期结束的时候
,counter==0,object
会被销毁
(
当然
,
这个销毁器本身可以由你定制
).
shared_ptr
的一个很大的特点是
:counter==0,object
会被销毁
;
反之
,
如果
counter
总是不为
0,
那么
object
会成为永久对象
,
例如全局对象
.
在
http://www.boost.org/doc/libs/1_35_0/libs/smart_ptr/sp_techniques.html
中给出了一个从
this
获得
shared_ptr
的实例
,
答案是使用
weak_ptr,
问题是为什么是
weak_ptr.
让我们把这个问题重新说明一下
:
struct X
{
boost::shared_ptr<X>
getX()
{
boost::shared_ptr<X>
r ;//????
如何实现
return r;
}
};
要得到
X
的智能指针
,
只是在对象指针是受
shared_ptr
保护的基础上的
,
举例如下
:
void test_X()
{
{
X x;
boost::shared_ptr<X> px =
x.getX();//
错误
}
{
X* x = new X();
boost::shared_ptr<X> px = x->getX();//
错误
}
{
boost::shared_ptr<X>
x (new X());
boost::shared_ptr<X> px = x->getX();//
正确
}
}
我们再回到原来的问题上
,
如何实现
X::getX()
函数
.
要构造
X
的智能指针
,
需要知道两个信息
,object
的指针和
object
的计数器
,
显然
,
指针本身可以通过
this
获得
,
问题是如何获得计数器
,
也即上面图中的
counter.
很显然
,
我们必须在
X
上存储某些信息来得到计数器
.
最先想到的也许是使用一个指向
counter
的指针存储在
X
上面
,
这样应该是可以的
,
但是存在一个问题
:
暴露了
shared_ptr
的实现细节
,
虽然
shared_ptr
是基于计数器的
,
但是这不属于用户需要知道的事情
.
最好的方式是让
shared_ptr
本身来充当这个角色
,
这样所有的实现细节就都封装在
shared_ptr
内部了
.
经过这样改装的
shared_ptr
的图解是
:
经过这样包装的
object,
问题立刻暴露出来
:
循环引用
,
造成
object
对象无法释放
,
成为
”
全局对象
”.
很显然
,
问题在于
object
本身参与了引用计数
,
也就是所有权的分享
.
我们需要的是不同于
shared_ptr
的这样的一类共享指针
:
他们并不参与对象的所有权
,
只是能够观察到对象的所有权
.
而这正是
weak_ptr
的本质所在
.
当然了
,weak_ptr
还有其他的特征
:
查看对象指针是否过期
(
这也是比裸指针好的地方
).
循环引用的情况很罕见
,
这可能也是我在实际中很少使用
weak_ptr
的原因吧
.
相关文章推荐
- boost::weak_ptr和enable_shared_from_this
- boost::weak_ptr和enable_shared_from_this
- boost::weak_ptr和enable_shared_from_this
- boost::weak_ptr和enable_shared_from_this
- boost::weak_ptr和enable_shared_from_this
- 对enable_shared_from_this、weak_ptr、shared_ptr的理解
- boost::shared_ptr递归调用解决办法--boost::enable_shared_from_this
- C++学习 std::tr1::shared_ptr、std::tr1::weak_ptr及std::tr1::enable_shared_from_this
- weak_ptr,enable_shared_from_this 的使用举例
- std::tr1::shared_ptr、std::tr1::weak_ptr及std::tr1::enable_shared_from_this
- weak_ptr 和enable_shared_from_this
- 如何用enable_shared_from_this 来得到指向自身的shared_ptr 及对enable_shared_from_this 的理解
- boost 库 enable_shared_from_this 实现原理分析
- boost::enable_shared_from_this的部分实现研究
- boost::enable_shared_from_this的用法
- shared_ptr,shared_ptr,enable_shared_from_this的理解
- boost 库 enable_shared_from_this 实现原理分析
- boost 库 enable_shared_from_this 实现原理分析
- Boost 库 Enable_shared_from_this 实现原理分析
- Boost 库 Enable_shared_from_this 实现原理分析