Boost中的智能指针(转)

news/2024/7/20 13:20:53 标签: c/c++, 内存管理

 

  这篇文章主要介绍 boost中的智能指针的使用。(转自:http://www.cnblogs.com/sld666666/archive/2010/12/16/1908265.html)

    内存管理是一个比较繁琐的问题,C++中有两个实现方案: 垃圾回收机制和智能指针。垃圾回收机制因为性能等原因不被C++的大佬们推崇, 而智能指针被认为是解决C++内存问题的最优方案。

1. 定义

     一个智能指针就是一个C++的对象, 这对象的行为像一个指针,但是它却可以在其不需要的时候自动删除。注意这个“其不需要的时候”, 这可不是一个精确的定义。这个不需要的时候可以指好多方面:局部变量退出函数作用域、类的对象被析构……。所以boost定义了多个不同的智能指针来管理不同的场景。

shared_ptr<T>内部维护一个引用计数器来判断此指针是不是需要被释放。是boost中最常用的智能指针了。
scoped_ptr<t>当这个指针的作用域消失之后自动释放
intrusive_ptr<T>也维护一个引用计数器,比shared_ptr有更好的性能。但是要求T自己提供这个计数器。
weak_ptr<T>弱指针,要和shared_ptr 结合使用
shared_array<T>和shared_ptr相似,但是访问的是数组
scoped_array<T>和scoped_ptr相似,但是访问的是数组

2. Boost::scoped_ptr<T>

    scoped_ptr 是boost中最简单的智能指针。scoped_ptr的目的也是很简单, 当一个指针离开其作用域时候,释放相关资源。特别注意的一定就是scoped_ptr 不能共享指针的所有权也不能转移所有权。也就是说这个内存地址就只能给的声明的变量用,不能给其他使用。

    下面是scoped_ptr的几个特点:

  1. scoped_ptr的效率和空间的消耗内置的指针差不多。
  2. scoped_ptr不能用在标准库的容器上。(用shared_ptr代替)
  3. scoped_ptr 不能指向一块能够动态增长的内存区域(用scoped_array代替)

 

复制代码
1 class test
2 {
3 public:
4 void print()
5 {
6 cout << "test print now" <<endl;
7 }
8 };
9 int _tmain(int argc, _TCHAR* argv[])
10 {
11 boost::scoped_ptr<test> x(new test);
12 x->print();
13 return 0;
14 }
复制代码

 

3.Boost::shared_ptr<T>

    shared_ptr 具有如下几个特点:

  1. 在内部维护一个引用计数器, 当有一个指针指向这块内存区域是引用计数+1, 反之-1, 如果没有任何指针指向这块区域, 引用计数器为0,释放内存区域。
  2. 可以共享和转移所有权。
  3. 可以被标准库的容器所使用
  4. 不能指向一块动态增长的内存(用share_array代替)

我们可以看下如下例子:

 

复制代码
1 int _tmain(int argc, _TCHAR* argv[])
2 {
3 boost::shared_ptr<test> ptr_1(new test);
4 ptr_1->print();//引用计数为1
5 boost::shared_ptr<test> ptr_2 = ptr_1;
6 ptr_2->print();//引用计数为2
7 ptr_1->print();// 引用计数还是为2
8 return 0;
9 }
复制代码

 

4. Boost::intrusive_ptr<T>

    intrusive_ptr 的主要和share_ptr一样, 对比share_ptr,其效率更高,但是需要自己维护一个引用计数器, 这里不做详细介绍。

5. Boost::weak_ptr<T>

    weak_ptr 就是一个弱指针。weak_ptr 被shared_ptr控制, 它可以通过share_ptr的构造函数或者lock成员函数转化为share_ptr。

    weak_ptr的一个最大特点就是它共享一个share_ptr的内存,但是无论是构造还是析构一个weak_ptr 都不会影响引用计数器。

 

复制代码
1 int _tmain(int argc, _TCHAR* argv[])
2 {
3 boost::shared_ptr<test> sharePtr(new test);;
4 boost::weak_ptr<test> weakPtr(sharePtr);
5 //weakPtr 就是用來保存指向這塊內存區域的指針的
6 //干了一大堆其他事情
7 boost::shared_ptr<test> sharePtr_2 = weakPtr.lock();
8 if (sharePtr_2)
9 sharePtr_2->print();
10 return 0;
11 }
复制代码

 

6. Boost::shared_array<T> 和Boost::scoped_array<T>

    前面提到过shared_ptr和scoped_ptr不能用于数组的内存(new []),所以shared_array和scoped_array就是他们的代替品。我们可以看下shared_array的用法

 

复制代码
1 int _tmain(int argc, _TCHAR* argv[])
2 {
3 const int size = 10;
4 boost::shared_array<test> a(new test[]);
5 for (int i = 0; i < size; ++i)
6 a[i].print();
7 return 0;
8 }
复制代码

 

7. 使用智能指针的几个注意点

    下面是几个使用智能指针需要注意的地方:

  1. 声明一个智能指针的时候要立即给它实例化, 而且一定不能手动释放它。
  2. …_ptr<T> 不是T* 类型。所以:

                a: 声明的时候要…_ptr<T> 而不是….._ptr<T*>

                b:不能把T* 型的指针赋值给它

                c: 不能写ptr=NULl, 而用ptr.reset()代替。

  1.   不能循环引用。
  2. 不要声明临时的share_ptr, 然后把这个指针传递给一个函数

8. 总结

    智能指针使用上还是比较简单的, 而且能比较有效得解决C++内存泄露的问题,各位使用C++的童鞋赶快用起来吧。

转载于:https://www.cnblogs.com/ToDoToTry/p/4310671.html


http://www.niftyadmin.cn/n/1316964.html

相关文章

Linux进程间通信的主要方式有哪些?

IPCIPC及网络编程管道进程间通信概念管道的概念及分类管道的概念及特点管道的分类管道编程1 创建管道消息队列共享内存信号量Linux网络编程基本套接口编程IPC及网络编程 管道 古老的进程间通信机制。 进程间通信概念 进程间通信是在不同进程间进行信息交换的机制。Linux进程…

Etcd源码分析-网络模型进阶篇

起初本篇打算介绍raft相关&#xff0c;但是后来发现&#xff0c;还是有必要再深入介绍一下网络模型。一、基础网络模型 Etcd采用http&#xff08;https&#xff09;协议作为应用层协议&#xff0c;关于http协议介绍不是本篇范畴。大家都知道http一般情况下是无状态协议&#xf…

Java:多线程二 同步

由于多线程的访问出现延迟和线程的随机性&#xff0c;在使用多线程时往往会伴随安全性的问题&#xff0c;这些问题一旦出现将会是非常严重的。为了解决这种安全性问题&#xff0c;synchronized出现了。 synchronized用法一&#xff0c;放在方法内&#xff0c;必须传一个对象obj…

解决使用express.render渲染ejs显示源码的问题

今天使用express实现服务器后台的时候发现使用ejs模板引擎进行渲染的时候总是出现源码&#xff0c;百思不得其解&#xff0c;百度搜了很多也没人遇到这种情况&#xff0c;倒是有人使用html解析引擎的时候出现源码&#xff0c;跟我的问题不一样。最后检查代码发现在设置response…

Etcd源码分析-Raft实现

从本篇开始介绍Raft&#xff0c;集群中最核心内容是保证数据一致性&#xff0c;那么如何保证数据一致性&#xff1f;在业界有很多算法、协议&#xff0c;例如&#xff1a;Paxos&#xff0c;Raft。 Raft协议相比之前协议Paxos等&#xff0c;算是年轻协议&#xff0c;而且…

cocoapods使用遇到的一些问题

很久以前的就使用过cocoapods&#xff0c;但是一段时间没有使用就有些忘记了&#xff0c;今天再次设计到这里&#xff0c;还是遇到了几个问题。 第一步&#xff1a;先确定系统的ruby版本是最新的 使用 sudo gem update --system&#xff0c;在电脑上安装最新的cocoapods &#…

js将long日期格式转换为标准日期格式

javaScript将long日期格式转换为标准日期格式的实例代码。 <!DOCTYPE html> <html><head></head><body><script language"javascript"> //扩展Date的format方法 Date.prototype.format function (format) {var o {"M&q…

js中判断对象具体类型

大家可能知道js中判断对象类型可以用typeof来判断&#xff0c;看下面的情况。 <script>alert(typeof 1);//numberalert(typeof "2");//stringalert(typeof [1,2,3]);//objectalert(typeof {"name":"zhuhui"})//object </script> 从上…