boost智能指针及chromium指针管理WeakPtr
来源:互联网 发布:c语言如何清屏 编辑:程序博客网 时间:2024/05/18 00:45
之前一直有用到智能指针,但一直没有真正去了解其内部的实现,并且之前用到的很多智能指针实现方式是经过封装过的,如Comptr这类。今天在研究chromium中的代码是看到了其自定义的WeakPtr的实现,感觉自己对这部分知识不甚了解,趁着这个机会,好好把跟智能指针相关的知识理清楚。在这篇文章会重点讲讲boost标准库和chromium中一些定义及使用。
首先,还是在boost中查看相关智能指针的实现,在C++中为了更好的管理内存,特别是管理那些动态分配且被多个对象拥有的对象,boost提出了一套智能指针(smart pointers)的标准。
boost中提出了6种智能指针的使用方式,下面表格中的内容是从官方文档中抠出来的,可以事先做一个简单的了解。
scoped_ptr<boost/scoped_ptr.hpp>单个对象的唯一的一个拥有者,不可复制。scoped_array<boost/scoped_array.hpp>数组对象的唯一的一个拥有者,不可复制。shared_ptr<boost/shared_ptr.hpp>多个指针共享单个对象。shared_array<boost/shared_array.hpp>
多个指针共享一个数组对象。
weak_ptr<boost/weak_ptr.hpp>一个被shared_ptr所拥有的对象的观察者(不拥有它)。intrusive_ptr<boost/intrusive_ptr.hpp>内部嵌入一个引用计数来拥有一个共享对象。 上述的6中智能指针都是std::auto_ptr模板的一个具体实现。
1、scoped_ptr:
scoped_ptr指向一个动态new出的对象,是一个相对简单的智能指针实现。当scoped_ptr自己被释放或者被手动执行reset的时候,它所指向的对象会被释放掉。这就是说,scoped_ptr所指向的对象只在当前作用域中有效。另外,由于它不可复制,所以当我们需要用到不用复制的对象时,使用scoped_ptr比使用shared_ptr或者std::auto_ptr更安全。
scoped_ptr不能用在标准库的容器上。可用shared_ptr代替
scoped_ptr 不能指向一块能够动态增长的内存区域。可用scoped_array代替。
scoped_ptr 不能指向一块能够动态增长的内存区域。可用scoped_array代替。
scoped_ptr使用实例如下:
程序执行后的结果: #include <boost/scoped_ptr.hpp> #include <iostream> struct Shoe { ~Shoe() { std::cout << "Buckle my shoe\n"; } }; class MyClass { boost::scoped_ptr<int> ptr; public: MyClass() : ptr(new int) { *ptr = 0; } int add_one() { return ++*ptr; } }; int main() { boost::scoped_ptr<Shoe> x(new Shoe); MyClass my_instance; std::cout << my_instance.add_one() << '\n'; std::cout << my_instance.add_one() << '\n'; }
1
2
Buckle my shoe
2、scoped_array:
它的实现方式很多和scoped_ptr一致,只是它管理的是一个数组对象,而不能管理单个对象。
3、intrusive_ptr:
intrusive_ptr的很多实现与share_ptr基本保持一致,但是它所管理的对象自己会维护一个引用计数。
4、share_ptr:
share_ptr指向一个动态new出的对象。当最后一个指向该对象的share_ptr被释放或者被手动执行reset的时候,所指向的对象会被释放掉。
share_ptr能够用于C++标准库的容器上。同时,因为它能够执行比较操作,所以它也能在C++标准关系容器中使用。
share_ptr的具体实现方式是采用引用计数的方式,所以当一个对象被循环引用的时候就会出现没法正常释放的情况,这是就要结合weak_ptr来打破这个循环。
使用实例:
void f(shared_ptr<int>, int);int g();void ok(){ shared_ptr<int> p(new int(2)); f(p, g());}
5、share_array:
实现与share_ptr类似,只是它管理的是一个数组对象,而不能管理单个对象,这里不做过多介绍。
6、weak_ptr:
weak_ptr中存储着已经被share_ptr管理对象的一个弱引用,weak_ptr要想使用所指向的对象,需要通过share_ptr的构造函数或者lock成员函数转化为share_ptr。当一个对象的所有share_ptr都释放掉且该对象自己也被删除的时候,如果再尝试从一个指向已删除对象的weak_ptr中获取share_ptr则会失败。失败时构造函数会返回一个boost::bad_weak_ptr类型的异常,而weak_ptr::lock 则会返回一个空的shared_ptr。
在share_ptr中有这么个构造函数定义:template<class Y> explicit shared_ptr(weak_ptr<Y> const & r);这个就是通过weak_ptr生成一个shared_ptr来访问该对象。
weak_ptr的一个最大特点就是它共享一个share_ptr的内存,但是无论是构造还是析构一个weak_ptr 都不会影响引用计数器。 weak_ptr使用实例:
shared_ptr<int> p(new int(5));weak_ptr<int> q(p);// some time laterif(shared_ptr<int> r = q.lock()){ // use *r}
了解了boost中的只能指针后,在来了解一写关于chromium中WeakPtr的知识:
首先我们需要了解一下WeakPtr为什么会出现。从Chrome源码剖析这篇文章中我们可以了解到chromium的代码中会尽量避免用锁来处理多线程的问题,而换用task的机制来完成多线程的实现。但使用task机制来处理多线程的时候经常会碰到这么个问题,就是当多个task共用一个对象是,我们该如何管理这个对象的生命周期,WeakPtr正是为了处理这个问题而出现的。关于WeakPtr如何解决上述的问题我们可以在《浅谈chromium中的指针管理》中进一步的了解,这篇文章介绍的相对比较详细。
通过上面的了解,总体上来说,chromium中的WeakPtr与boost中的weak_ptr虽然都叫弱指针,但它们所要描述的东西却完全不一样,实现方式也完全不一样,要注意区分。
另外,在chromium的文档中还这么描述了WeakPtr。弱指针主要是使用在那些拥有多个引用计数,并且不希望自己的生命周期与这些引用计数绑定在一起的对象上。
下面有这么一段示例代码:
class Controller : public SupportsWeakPtr<Controller> { public: void SpawnWorker() { Worker::StartNew(AsWeakPtr()); } void WorkComplete(const Result& result) { ... } }; class Worker { public: static void StartNew(const WeakPtr<Controller>& controller) { Worker* worker = new Worker(controller); // Kick off asynchronous processing... } private: Worker(const WeakPtr<Controller>& controller) : controller_(controller) {} void DidCompleteAsynchronousProcessing(const Result& result) { if (controller_) controller_->WorkComplete(result); } WeakPtr<Controller> controller_;};
在这个示例中,用户可能会动态分配一个Controller的对象,之后再调用几次SpawnWorker,当所有的Works都完成后再销毁Controller,因为Worker中仅仅是维持一个Controller的弱指针,所以我们无需担心Worker在Controller释放后再对Controller解除引用。
讲到这里,顺便插播个广告,google的code search着实很强大,在里面搜代码定位非常准确,感兴趣的话可以试试。
此文讲述的还不够全面,还需进一步了解chromium中WeakPtr这个强大的实现方式。
boost smart pointers:
http://www.boost.org/doc/libs/1_52_0/libs/smart_ptr/smart_ptr.htm
Exception Safe Smart Pointers:
http://webcache.googleusercontent.com/search?q=cache:_n8cbXGp3ZoJ:www.open-std.org/jtc1/sc22/wg21/docs/papers/1994/N0555.ps+&cd=1&hl=zh-CN&ct=clnk&gl=cn
- boost智能指针及chromium指针管理WeakPtr
- boost智能指针及chromium指针管理WeakPtr
- Boost 内存管理----智能指针
- Chromium 智能指针实现
- 智能指针——AutoPtr & ScopedPer & SharedPtr & WeakPtr
- boost中的智能指针shared_ptr的指针管理
- Boost的智能指针
- 智能指针:boost学习
- Boost中的智能指针
- boost智能指针
- 【Boost】智能指针
- 使用Boost智能指针
- boost智能指针介绍
- Boost智能指针学习
- Boost智能指针:shared_ptr
- Boost智能指针小记
- Boost 中的智能指针
- boost:智能指针
- 记录点滴33
- [攻克存储] 存储芯片的写屏蔽及扩展
- Ajax工作原理
- 多线程编程 -wait(),notify()/notityAll()方法
- [攻克存储] 掌握SDRAM/DDR的结构与寻址
- boost智能指针及chromium指针管理WeakPtr
- VS2010进行autocad无法调试的解决办法
- [攻克存储] s3c2440存储系统设计与思考
- java 细节 split List 中的equal
- usaco-cowcycle
- 获取HICON
- Delphi 7 企业版光盘镜像 附破解 update 1
- SharePoint 2010 导航菜单定制
- 控件水平居中或垂直居中