浅析Boost智能指针:scoped
一. scoped_ptr 复制代码 代码如下: #include <string> #include <iostream> #include <boost/scoped_ptr.hpp> class implementation void test() void main() 该代码的输出结果是: 复制代码 代码如下: Test Begin ... did something destroying implementation Test End. 可以看到:当implementation类离其开impl作用域的时候,会被自动删除,这样就会避免由于忘记手动调用delete而造成内存泄漏了。 boost::scoped_ptr特点: 1.不能转换所有权 2.不能共享所有权 3.不能用于管理数组对象 复制代码 代码如下: namespace boost { template<typename T> class scoped_ptr : noncopyable { void reset(T* p = 0); T& operator*() const; void swap(scoped_ptr& b); template<typename T> 它的常用操作如下:
下列测试代码演示了这些功能函数的基本使用方法。 复制代码 代码如下: #include <string> #include <iostream> #include <boost/scoped_ptr.hpp> #include <boost/config.hpp> void test() *sp = 1234568901L; long * lp2 = new long; sp.swap(sp2); sp.reset(NULL); } void main() boost::scoped_ptr和std::auto_ptr的选取: boost::scoped_ptr和std::auto_ptr的功能和操作都非常类似,如何在他们之间选取取决于是否需要转移所管理的对象的所有权(如是否需要作为函数的返回值)。如果没有这个需要的话,大可以使用boost::scoped_ptr,让编译器来进行更严格的检查,来发现一些不正确的赋值操作。 二. shared_ptr 复制代码 代码如下: #include <string> #include <iostream> #include <boost/shared_ptr.hpp> class implementation void test() boost::shared_ptr<implementation> sp2 = sp1; sp2.reset(); void main() 该程序的输出结果如下: 复制代码 代码如下: The Sample now has 1 references The Sample now has 2 references After Reset sp1. The Sample now has 1 references destroying implementation After Reset sp2. 可以看到,boost::shared_ptr指针sp1和sp2同时拥有了implementation对象的访问权限,且当sp1和sp2都释放对该对象的所有权时,其所管理的的对象的内存才被自动释放。在共享对象的访问权限同时,也实现了其内存的自动管理。 boost::shared_ptr的内存管理机制: 上面的那个例子可以的图示如下: 1.sp1对implementation对象进行管理,其引用计数为1 2.增加sp2对implementation对象进行管理,其引用计数增加为2 3.sp1释放对implementation对象进行管理,其引用计数变为1 4.sp2释放对implementation对象进行管理,其引用计数变为0,该对象被自动删除 boost::shared_ptr的特点: boost::shared_ptr的使用规则: 1.避免对shared_ptr所管理的对象的直接内存管理操作,以免造成该对象的重释放 如下列代码则可能导致内存泄漏: 复制代码 代码如下: void test() { foo(boost::shared_ptr<implementation>(new implementation()),g()); } 正确的用法为: void test() { boost::shared_ptr<implementation> sp (new implementation()); foo(sp,g()); } 三. weak_ptr 循环引用: 复制代码 代码如下: #include <string> #include <iostream> #include <boost/shared_ptr.hpp> #include <boost/weak_ptr.hpp> class parent; typedef boost::shared_ptr<parent> parent_ptr; class parent public: class children public:
father->children = son; void main() 运行该程序可以看到,即使退出了test函数后,由于parent和children对象互相引用,它们的引用计数都是1,不能自动释放,并且此时这两个对象再无法访问到。这就引起了c++中那臭名昭著的内存泄漏。 一般来讲,解除这种循环引用有下面有三种可行的方法: 虽然这三种方法都可行,但方法1和方法2都需要程序员手动控制,麻烦且容易出错。这里主要介绍一下第三种方法和boost中的弱引用的智能指针boost::weak_ptr。 强引用和弱引用 相对而言,弱引用当引用的对象活着的时候不一定存在。仅仅是当它存在的时候的一个引用。弱引用并不修改该对象的引用计数,这意味这弱引用它并不对对象的内存进行管理,在功能上类似于普通指针,然而一个比较大的区别是,弱引用能检测到所管理的对象是否已经被释放,从而避免访问非法内存。 复制代码 代码如下: boost::weak_ptr boost::weak_ptr<T>是boost提供的一个弱引用的智能指针,它的声明可以简化如下: namespace boost { template<typename T> class weak_ptr { weak_ptr(const weak_ptr& r); ~weak_ptr(); T* get() const; 可以看到,boost::weak_ptr必须从一个boost::share_ptr或另一个boost::weak_ptr转换而来,这也说明,进行该对象的内存管理的是那个强引用的boost::share_ptr。boost::weak_ptr只是提供了对管理对象的一个访问手段。 boost::weak_ptr除了对所管理对象的基本访问功能(通过get()函数)外,还有两个常用的功能函数:expired()用于检测所管理的对象是否已经释放;lock()用于获取所管理的对象的强引用指针。 通过boost::weak_ptr来打破循环引用 复制代码 代码如下: class children { public: ~children() { std::cout <<"destroying childrenn"; } public: 最后值得一提的是,虽然通过弱引用指针可以有效的解除循环引用,但这种方式必须在程序员能预见会出现循环引用的情况下才能使用,也可以是说这个仅仅是一种编译期的解决方案,如果程序在运行过程中出现了循环引用,还是会造成内存泄漏的。因此,不要认为只要使用了智能指针便能杜绝内存泄漏。毕竟,对于C++来说,由于没有垃圾回收机制,内存泄漏对每一个程序员来说都是一个非常头痛的问题。 您可能感兴趣的文章:
(编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |