boost::shared_ptr内存管理
来源:互联网 发布:商超网络信息平台 编辑:程序博客网 时间:2024/06/06 17:56
1、shared_ptr的基本用法
boost::shared_ptr<int> sp(new int(10)); //一个指向整数的shared_ptr assert(sp.unique()); //现在shared_ptr是指针的唯一持有者 boost::shared_ptr<int> sp2 = sp; //第二个shared_ptr,拷贝构造函数 assert(sp == sp2 && sp.use_count() == 2); //两个shared_ptr相等,指向同一个对象,引用计数为2 *sp2 = 100; //使用解引用操作符修改被指对象 assert(*sp == 100); //另一个shared_ptr也同时被修改 sp.reset(); //停止shared_ptr的使用,引用计数减一 assert(!sp); //sp不再持有任何指针(空指针) assert(sp2.use_count() == 1); //sp2引用计数变为1 sp.reset(new int(20)); //sp管理一个新对象 assert(*sp == 20);
2、应用于标准容器
有两种方式可以将shared_ptr应用于标准容器(或者容器适配器等其他容器)。
一种用法是将容器作为shared_ptr管理的对象,如shared_ptr<list<T> >,使容器可以被安全地共享,用法与普通shared_ptr没有区别,我们不再讨论。
另一种用法是将shared_ptr作为容器的元素,如vector<shared_ptr<T> >,因为shared_ptr支持拷贝语义和比较操作,符合标准容器对元素的要求,所以可以实现在容器中安全地容纳元素的指针而不是拷贝。
标准容器不能容纳auto_ptr,这是C++标准特别规定的(读者永远也不要有这种想法)。标准容器也不能容纳scoped_ptr,因为scoped_ptr不能拷贝和赋值。标准容器可以容纳原始指针,但这就丧失了容器的许多好处,因为标准容器无法自动管理类型为指针的元素,必须编写额外的大量代码来保证指针最终被正确删除,这通常很麻烦很难实现。
存储shared_ptr的容器与存储原始指针的容器功能几乎一样,但shared_ptr为程序员做了指针的管理工作,可以任意使用shared_ptr而不用担心资源泄漏。
#include <boost/make_shared.hpp> int main() { typedef vector<shared_ptr<int> > vs; //一个持有shared_ptr的标准容器类型 vs v(10); //声明一个拥有10个元素的容器,元素被初始化为空指针 int i = 0; for (vs::iterator pos = v.begin(); pos != v.end(); ++pos) { (*pos) = make_shared<int>(++i); //使用工厂函数赋值 cout << *(*pos) << ", "; //输出值 } cout << endl; shared_ptr<int> p = v[9]; *p = 100; cout << *v[9] << endl; }
这段代码需要注意的是迭代器和operator[]的用法,因为容器内存储的是shared_ptr,我们必须对迭代器pos使用一次解引用操作符*以获得shared_ptr,然后再对shared_ptr使用解引用操作符*才能操作真正的值。*(*pos)也可以直接写成**pos,但前者更清晰,后者很容易让人迷惑。vector的operator[]用法与迭代器类似,也需要使用*获取真正的值。
3、使用助手类enable_shared_from_this
为什么要使用enable_shared_from_this,或许你对这个类感到很迷惑,先看看下面这种情况:
class MyPoint{public: MyPoint(){std::cout << "MyPoint" << std::endl;} ~MyPoint(){std::cout << "~MyPoint" << std::endl;} //返回this的函数 boost::shared_ptr<MyPoint> GetPoint() { return boost::shared_ptr<MyPoint>(this); //错误,将返回一个新的引用计数 }};int _tmain(int argc, _TCHAR* argv[]){ boost::shared_ptr<MyPoint> p1(new MyPoint); boost::shared_ptr<MyPoint> p2 = p1->GetPoint(); std::cout << p1.use_count() << "," << p2.use_count() << std::endl; //输出引用计数情况 p1.reset(); //内存将被释放}
我们得到的答案将是:
MyPoint
1,1
~MyPoint
怎么正确的返回this呢,那么就需要借助enable_shared_from_this了,引入enable_shared_from_this的原因是可以实现返回值为指向该类本身的shared_ptr
正确的写法应该是这样的:
class MyPoint : public boost::enable_shared_from_this<MyPoint>{public: MyPoint(){std::cout << "MyPoint" << std::endl;} ~MyPoint(){std::cout << "~MyPoint" << std::endl;} //返回this的函数 boost::shared_ptr<MyPoint> GetPoint() { return shared_from_this(); }};int _tmain(int argc, _TCHAR* argv[]){ boost::shared_ptr<MyPoint> p1(new MyPoint); boost::shared_ptr<MyPoint> p2 = p1->GetPoint(); std::cout << p1.use_count() << "," << p2.use_count() << std::endl; //输出引用计数情况 p1.reset(); //内存将被释放}
4、定制删除器
当你在使用windows API函数进行编程时,你最烦的或许就是怎么保证申请的内核对象是否关闭,考虑一下代码:
int *p = (int*) HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(p) ); //业务处理 //...... HeapFree( GetProcessHeap(), 0, p );
对象不能通过delete来删除,而是一个释放函数,shared_ptr能否胜任呢,答案是肯定的。
int *p = (int*) HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(p) ); //此处使用了lambda表达式,需要vs2010或更高版本的支持 boost::shared_ptr<int> ptr(p, [](int *p){HeapFree( GetProcessHeap(), 0, p );});
5、综合应用示例
下面实现一个线程类,在线程运行结束时,能够自行清理自己的内存
#include <set>#include <Windows.h>#include <boost/thread.hpp>class MySelf;std::set< boost::shared_ptr<MySelf> > myList;boost::thread *ptrTh;class MySelf: public boost::enable_shared_from_this<MySelf>{public: MySelf() { printf("MySelf\n"); } void StartThread() { //启动一个线程 ptrTh = new boost::thread(&MySelf::Run, this); } void Run() { //线程任务函数 Sleep(5000); printf("stop thread\n"); Stop(); } void Stop() { //删除自己 myList.erase(shared_from_this()); } ~MySelf() { printf("~MySelf\n"); }};void TestSharePtr(){ boost::shared_ptr<MySelf> ptr1(new MySelf); //保存到list中 myList.insert(ptr1); ptr1->StartThread();}
- boost::shared_ptr内存管理
- boost源码剖析3----内存管理shared_ptr
- boost shared_ptr 及C++内存管理的一些总结
- boost>shared_ptr
- Boost - shared_ptr
- boost>shared_ptr
- boost>shared_ptr
- boost::shared_ptr
- boost::shared_ptr
- boost>shared_ptr
- boost::shared_ptr
- 内存管理 Boost::singleton_pool
- 内存管理 Boost::singleton_pool
- boost的内存管理
- boost 内存管理
- boost::shared_ptr boost::make_shared
- C++内存管理利器shared_ptr V2.0
- boost中的智能指针shared_ptr的指针管理
- java单例读取配置文件
- linux 内核poll/select/epoll实现剖析
- HTTP协议详解
- IIS 发布网站无法加载CSS、背景及图片文件
- 将 Windows IPC 应用移植到 Linux,第 1 部分: 进程和线程
- boost::shared_ptr内存管理
- C#MVC中自带验证
- PostgresSQL
- asp.net mvc新建运行Debug时,提示 此操作要求使用 IIS 集成管线模式
- 用debugserver + lldb代替gdb进行动态调试
- libc2.14安装
- java7并发编程学习笔记
- linux反汇编
- 系统图标和其它应用程序快捷方式异常:“图标文字后缀全部变成.lnk”解决方法