您的位置:首页 > 其它

智能指针shared_ptr的一些综合

2016-07-22 11:56 387 查看
Smart Pointer,可以有效防止内存泄露问题。

shared_ptr与scoped_ptr一样包装了new操作符在堆上分配的动态对象,但它实现的是引用计数型的智能指针 ,可以被自由地拷贝和赋值,在任意的地方共享它,当没有代码使用(引用计数为0)它时才删除被包装的动态分配的对象。shared_ptr也可以安全地放到标准容器中,并弥补了auto_ptr因为转移语义而不能把指针作为STL容器元素的缺陷。

    - 一个 shared_ptr 实体可被多个线程同时读取;
    - 两个的 shared_ptr 实体可以被两个线程同时写入,“析构”算写操作;
    - 如果要从多个线程读写同一个 shared_ptr 对象,那么需要加锁。

智能指针(smart pointer)的一种通用实现技术是使用引用计数(reference count)。智能指针类将一个计数器与类指向的对象相关联,引用计数跟踪该类有多少个对象的指针指向同一对象。shared_ptr,允许共享对象所有权。

 shared_ptr完成了你所希望的工作:他负责在不使用实例时删除由它指向的对象(pointee),并且它可以自由的共享它指向的对象(pointee)。

shared_ptr的思想是,每当另一个智能指针指向该空间时,引用计数++,每当有智能指针更改指向时,引用计数–。这就意味着,有几个智能指针指向该空间,引用计数就是几,当引用计数大于2时,证明有2个以上的智能指针指向该空间,那么析构时,把智能指针赋空,不需释放空间。当且仅当引用计数为1时,即只有一个指针指向该空间,析构时才将指针赋空并释放空间,证明没有任何代码需要管理该空间,就把它释放掉。
shared_ptr的构架如图所示: 

当将指针传给shared_ptr时,class shared_ptr构造对象,px指向该指针指向的空间,而pn是shared_count类的,所以先构造shared_count的对象,shared_count(Ty
*p):pi(new sp_counted_impl_xxx<_Ty>(p)),构造对象时p是子类sp_counted_impl_xxx类型的,所以要先构造父类sp_counted_base的对象。
操作函数 
shared_ptr与scoped_ptr同样是管理new动态分配对象的智能指针,因此功能上有很多的相似之处:它们都重载了*和->操作符以模仿原始指针的行为,提供隐式bool类型转换以判断指针的有效性,get()可以得到原始指针,并且没有提供指针算术操作。

用法 

shared_ptr的智能使得其行为最接近原始指针,因此它比auto_ptr和scoped_ptr的应用更广。几乎是100%可以在任何new出现的地方接受new的动态分配结果,然后被任意的使用,从而完全消灭delete的使用和内存泄漏。


 boost::shared_ptr的用法

下面用一个简单的例子说明shared_ptr的用法:

1

2

3

4

5

6

7

8

9

10

11

12

13

14
#include <stdio.h>

#include <boost shared_ptr.hpp=
""
>

 
class
A
{

public
:

    
void
print()
{

        
printf(
"class
A print!\n"
);

    
}

};

 
int
main(
int
argc, 
char
**argv)
{

    
boost::shared_ptr
a1(
new
A());

    
a1->print();

}</boost></stdio.h>


shared_ptr不用手动去释放资源,它会智能地在合适的时候去自动释放。如上面的例子,a1指向的对象将会在程序结束的时候自动释放(程序结束时所有申请的资源都会被释放,这只是为了说明其作用)。

再来看下面的例子:

?
1

2

3

4

5

6

7

8

9

10

11

12
//同上

 
int
main(
int
argc, 
char
**argv)
{

    
boost::shared_ptr
a1(
new
A());

    
a1->print();

    
printf(
"a1
reference count: %d\n"
, a1.use_count());

    
boost::shared_ptr
a2 = a1;

    
printf(
"a1
reference count: %d\n"
, a1.use_count());

    
printf(
"a2
reference count: %d\n"
, a2.use_count());

    
a1.reset();

    
printf(
"a2
reference count: %d\n"
, a2.use_count());

}


程序输出结果:

1

2

3

4

5
class
A
print!

a1 reference count: 
1

a1 reference count: 
2

a2 reference count: 
2

a2 reference count: 
1


上面调用了两上shared_ptr的成员方法,user_count()的作用是获得当前对象被引用的次数,reset()的作用是释放指针对对象的引用,将指针设为空。

2. boost::shared_ptr的实现机制

boost::shared_ptr的实现机制其实比较简单,就是对指针引用的对象进行引用计数,当有一个新的boost::shared_ptr指针指向一个对象时,就把该对象的引用计数加1,减少一个boost::shared_ptr指针指向一个对象时,就把对该对象的引用计数减1。当一个对象的引用计数变为0时,就会自动调用其析构函数或者free掉相应的空间。
////////////////////////////////////////////////////////////////////////////////////////////////////
重点是如何要知道px是指向内存的指针,pn是记录有多少指针指向同一块内存。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: