boost中的智能指针的使用-------解决C++内存问题的最优方案

2024-06-15 03:48

本文主要是介绍boost中的智能指针的使用-------解决C++内存问题的最优方案,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!


内存管理是一个比较繁琐的问题,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的几个特点:

scoped_ptr的效率和空间的消耗内置的指针差不多。

scoped_ptr不能用在标准库的容器上。(用shared_ptr代替)

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

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

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

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

1.     不能循环引用。

2.    不要声明临时的share_ptr, 然后把这个指针传递给一个函数

8.总结

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

 

这篇关于boost中的智能指针的使用-------解决C++内存问题的最优方案的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1062345

相关文章

怎样通过分析GC日志来定位Java进程的内存问题

《怎样通过分析GC日志来定位Java进程的内存问题》:本文主要介绍怎样通过分析GC日志来定位Java进程的内存问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、GC 日志基础配置1. 启用详细 GC 日志2. 不同收集器的日志格式二、关键指标与分析维度1.

Linux中压缩、网络传输与系统监控工具的使用完整指南

《Linux中压缩、网络传输与系统监控工具的使用完整指南》在Linux系统管理中,压缩与传输工具是数据备份和远程协作的桥梁,而系统监控工具则是保障服务器稳定运行的眼睛,下面小编就来和大家详细介绍一下它... 目录引言一、压缩与解压:数据存储与传输的优化核心1. zip/unzip:通用压缩格式的便捷操作2.

Java内存分配与JVM参数详解(推荐)

《Java内存分配与JVM参数详解(推荐)》本文详解JVM内存结构与参数调整,涵盖堆分代、元空间、GC选择及优化策略,帮助开发者提升性能、避免内存泄漏,本文给大家介绍Java内存分配与JVM参数详解,... 目录引言JVM内存结构JVM参数概述堆内存分配年轻代与老年代调整堆内存大小调整年轻代与老年代比例元空

Java 线程安全与 volatile与单例模式问题及解决方案

《Java线程安全与volatile与单例模式问题及解决方案》文章主要讲解线程安全问题的五个成因(调度随机、变量修改、非原子操作、内存可见性、指令重排序)及解决方案,强调使用volatile关键字... 目录什么是线程安全线程安全问题的产生与解决方案线程的调度是随机的多个线程对同一个变量进行修改线程的修改操

使用Python实现可恢复式多线程下载器

《使用Python实现可恢复式多线程下载器》在数字时代,大文件下载已成为日常操作,本文将手把手教你用Python打造专业级下载器,实现断点续传,多线程加速,速度限制等功能,感兴趣的小伙伴可以了解下... 目录一、智能续传:从崩溃边缘抢救进度二、多线程加速:榨干网络带宽三、速度控制:做网络的好邻居四、终端交互

Python中注释使用方法举例详解

《Python中注释使用方法举例详解》在Python编程语言中注释是必不可少的一部分,它有助于提高代码的可读性和维护性,:本文主要介绍Python中注释使用方法的相关资料,需要的朋友可以参考下... 目录一、前言二、什么是注释?示例:三、单行注释语法:以 China编程# 开头,后面的内容为注释内容示例:示例:四

从入门到精通C++11 <chrono> 库特性

《从入门到精通C++11<chrono>库特性》chrono库是C++11中一个非常强大和实用的库,它为时间处理提供了丰富的功能和类型安全的接口,通过本文的介绍,我们了解了chrono库的基本概念... 目录一、引言1.1 为什么需要<chrono>库1.2<chrono>库的基本概念二、时间段(Durat

Redis出现中文乱码的问题及解决

《Redis出现中文乱码的问题及解决》:本文主要介绍Redis出现中文乱码的问题及解决,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录1. 问题的产生2China编程. 问题的解决redihttp://www.chinasem.cns数据进制问题的解决中文乱码问题解决总结

C++20管道运算符的实现示例

《C++20管道运算符的实现示例》本文简要介绍C++20管道运算符的使用与实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧... 目录标准库的管道运算符使用自己实现类似的管道运算符我们不打算介绍太多,因为它实际属于c++20最为重要的

Visual Studio 2022 编译C++20代码的图文步骤

《VisualStudio2022编译C++20代码的图文步骤》在VisualStudio中启用C++20import功能,需设置语言标准为ISOC++20,开启扫描源查找模块依赖及实验性标... 默认创建Visual Studio桌面控制台项目代码包含C++20的import方法。右键项目的属性: