智能指针shared_ptr的一些综合

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是记录有多少指针指向同一块内存。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
shared_ptr是一种智能指针,它是C++11引入的一种新特性。shared_ptr的设计思路是利用三个主要组件来实现智能指针的功能:一块空间、计数器和锁。 首先,shared_ptr通过一块堆空间来存储所指向的对象。这个堆空间是由shared_ptr自动管理的,当最后一个指向对象的shared_ptr被销毁时,这块空间会被释放。 其次,shared_ptr使用一个计数器来记录当前有多少个shared_ptr共享同一个对象。每当有一个新的shared_ptr指向对象时,计数器就会加1;当有一个shared_ptr被销毁时,计数器就会减1。当计数器为0时,表示没有任何shared_ptr指向对象,此时对象会被释放。 最后,shared_ptr还使用锁来确保多线程环境下的安全访问。由于shared_ptr是可以被多个指针共享的,因此在多线程环境中,可能存在多个线程同时操作同一个shared_ptr。为了避免竞争条件,shared_ptr内部使用了锁来保证多线程操作的原子性和线程安全性。 总结起来,shared_ptr实现了智能指针的功能,通过一块空间、计数器和锁来管理所指向对象的生命周期。它可以跟踪对象的引用计数,并在最后一个shared_ptr被销毁时自动释放对象。同时,shared_ptr还具备多线程安全的特性,可以在多线程环境下使用。 参考文献: 前面介绍的auto_ptr和unique_ptr都存在着些许的缺陷,显得不是那么的“智能”,下面我们来看一下较为智能的shared_ptr的设计思路(一块空间、计数器、锁) 主要介绍了C++11新特性之智能指针,包括shared_ptr, unique_ptr和weak_ptr的基本使用,感兴趣的小伙伴们可以参考一下 这是因为weak_ptr是一种不控制所指向对象生存期的智能指针,它指向由一个shared_ptr管理的对象。将一个weak_ptr绑定到shared_ptr不会改变shared_ptr的引用计数。一旦最后一个指向对象的shared_ptr被销毁,对象就会被释放。即使weak_ptr指向对象,对象也会被释放。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值