boost 智能指针auto_ptr scoped_ptr shared_ptr scoped_array shared_array 总结

2024-06-15 03:48

本文主要是介绍boost 智能指针auto_ptr scoped_ptr shared_ptr scoped_array shared_array 总结,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!


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相似,但是访问的是数组


C++没有自动内存回收机制,程序员new出来的对象需要delete掉,否则就是写法的不严密,在大型项目开发中尤其重要,幸好C++中有智能指针可以缓解这个内存回收的问题,下面是对常用的智能指针的总结:
智能指针是一个栈对象,并非指针类型,在栈对象生命周期即将结束的时候,智能指针通过析构函数释放它所管理的内存,所有智能指针都重载了operator->操作符
下面来个测试类,下面的讲解都是按照这个类分析的:
class Simple{
public:
    Simple(int param=0){
        number=param;
        cout<<"Simple:"<<number<<endl;
    }
    ~Simple(){
        cout<<"~Simple"<<number<<endl;
    }
    void PrintSomething(){
        cout<<"PrintSomething:"<<info_extend.c_str()<<endl;
    }
    
    string info_extend;
    int number;
};

智能指针auto_ptr
auto_ptr属于STL,使用的时候包含头文件#include <memeory>,auto_ptr能够方便的管理单个内存对象
void testautoptr(){
    auto_ptr<Simple> my_memory(new Simple(1));
    if(my_memory.get()){//判断智能指针是否为空
        my_memory->PrintSomething();
        my_memory.get()->info_extend="www.jiaojiaoni.com";
        my_memory->PrintSomething();
        (*my_memory).info_extend+=" my website!";
        my_memory->PrintSomething();
    }
}
执行结果:
Simple: 1
PrintSomething:
PrintSomething: Addition
PrintSomething: Addition other
~Simple: 1
上面是auto_ptr使用的简单例子,我们不用再显示的使用delete语句了,在使用auto_ptr的时候,绝对不能使用operator=操作符,因为=操作符会剥夺原有智能指针对于内存的管理权从而导致其悬空。
下面来一个悬空的例子:
void testautoptr2(){
    auto_ptr<Simple> my_memory(new Simple(1));
    if(my_memory.get()){
        auto_ptr<Simple> my_memory2;
        my_memory2=my_memory;
        my_memory2->PrintSomething();
        my_memory->PrintSomething();//其权限已经被剥夺,是空的了访问崩溃
    }
}

在某些内存受限的系统中,如果auto_ptr指针占用太多的内存,我们会考录在使用完后立刻归还,而不是等到该智能指针结束声明期后才归还,但是需要注意的是:auto_ptr中的release()函数只是让出内存的所有权
下面来个正确归还的例子:
void testautoptr3(){
    auto_ptr<Simple> my_memory(new Simple(1));
    if(my_memory.get()){
        Simple* temp_memory=my_memory.release();
        delete temp_memory;
    }
}
或者下面的方法:
void testautoptr4(){
    auto_ptr<Simple> my_memory(new Simple(1));
    if(my_memory.get()){
        my_memory.reset();//释放智能指针内存管理的内存
    }
}
总之记住:release()函数只是让出了内存的所有权,并没有释放内存,reset()函数可以。
下面是对auto_ptr智能指针的总结:
1) auto_ptr可以用来管理单个对象的内存
2) 尽量不要使用operator=操作符,如果使用了,不要再使用先前的对象
3) release函数不会释放内存,仅仅归还所有权
4) auto_ptr不要做为参数,原因类似于第二条
5) auto_ptr管理的对象不能放入vector等容器内,因为有=问题
鉴于auto_ptr存在上述的问题,现在给大家推荐一个更好的智能指针

智能指针boost::scoped_ptr
该指针属于boost库,定义在命名空间namespace boost中,需要包含头文件#include <boost/smart_ptr.hpp>
boost::scoped_ptr和std::auto_ptr一样,可以方便的管理单个堆内存对象,特别的是boost::scoped_ptr独享所有权,避免了std::auto_ptr恼人的几个问题
void testscopedptr(){
    boost::scoped_ptr<Simple> my_memory(new Simple(1));
    if(my_memory.get()){
        my_memory->PrintSomething();
        my_memory.get->info_extend="www.jiaojiaoni.com";
        my_memory->PrintSomething();
        (*my_memory).info_extend+=" my website!";
        my_memory->PrintSomething();

        my_memory.release();//ERROR scoped_ptr没有release函数
        boost::scoped_ptr<Simple> my_memory2=my_memory;//ERROR scoped_ptr没有重载operator=操作符,不会发生所有权转移,实际上其会独享所有权,所以不支持赋值功能,如果需要复制,那么可以使用下面的指针,其专门处理复制参数传递等情况,详见下篇
    }
}

boost::shared_ptr  (用于管理单个堆内存对象)
boost::shated_ptr定义在命名空间boost中,包含头文件#include<boost/smart_ptr.hpp>中,和上述的boost::scoped_ptr是一个文件里,但是scoped_ptr独享所有权不允许赋值拷贝,boost::shared_ptr是专门用于共享所有权的,其内有引用计数
例子:
void testsharedptr(boost::shared_ptr<Simple> memory){//无须引用
    memory->PrintSomething();
    cout<<"testsharedptr usecount:"<<memory.use_count()<<endl;//引用次数
}
void testsharedptr2(){
    boost::shared_ptr<Simple> my_memory(new Simple(1));
    if(my_memory.get()){
        my_memory->PrintSomething();
        my_memory.get()->info_extend="www.jiaojiaoni.com";
        my_memory->PrintSomething();
        (*my_memory).info_extend+=" my website!";
        my_memory->PrintSomething();
    }
    cout<<"testsharedptr2 usecount:"<<my_memory.use_count()<<endl;
    testsharedptr(my_memory);
    cout<<"testsharedptr2 usecount:"<<my_memory.use_count()<<endl;
    my_memory.release();//编译error,没有该函数
}
boost::shared_ptr内部维护了一个引用计数,由此可以方便的支持复制 参数传递等操作,因此在我们需要一个共享内存对象的时候,boost::shared_ptr是再好不过了。

上面介绍的都是对单个内存对象的操作,我们也可以用智能指针对数组进行操作

智能指针boost::scoped_array
boost::scoped_array属于boost库,定义在namespace boost中,使用的时候需要包含头文件#include <boost/smart_ptr.hpp>即可
boost::scoped_array是用于管理动态数组问题的,独享所有权
例子:
void testscopedarray(){
    boost::scoped_array<Simple> my_memory(new Simple[2]);
    if(my_memory.get()){
        my_memory[0].PrintSomething();
        my_memory.get()[0].info_extend="www.jiaojiaoni.com";
        my_memory[0].PrintSomething();
    //scoped_array没有从在取值* release 和复制=操作符
    }
}

智能指针boost::shared_array
boost::shared_array跟boost::shared_ptr一样,内部使用了引用计数
例子:
void testsharedarray(boost::shared_array<Simple> memory){
    cout<<"testsharedarray usecount:"<<memory.use_count()<<endl;
}
void testsharedarray2(){
    boost::shared_array<Simple> my_memory(new Simple[2]);
    if(memory.get()){
        my_memory[0].PrintSomething();
        my_memory.get()[0].info_extend="www.jiaojiaoni.com";
        my_memory[0].PrintSomething();
        my_memory[1].PrintSomething();
        my_memory.get()[1].info_extend="jiaojiaoni.com";
        my_memory[1].PrintSomething();
    }
    cout<<"testsharedarray2 usecount:"<<my_memory.use_count()<<endl;
    testsharedarray(my_memory);
        cout<<"testsharedarray2 usecount:"<<my_memory.use_count()<<endl;
}
编译运行结果:
Simple: 0
Simple: 0
PrintSomething:
PrintSomething: Addition 00
PrintSomething:
PrintSomething: Addition 11
TestSharedArray2 UseCount: 1
TestSharedArray UseCount: 2
TestSharedArray2 UseCount: 1
~Simple: 0
~Simple: 0

下面对智能指针整体总结一下
1)在可以使用boost库的场合下,不要使用std::auto_ptr因为其不符合C++编程思想,并且容易出错
2)在确定对象无须共享的情况下,使用boost::scoped_ptr/array
3)在对象需要共享的情况下,使用boost::shared_ptr/array
4)在你的代码中不要出现delete或free函数了,因为可以用智能指针去管理,除非有硬性要求


这篇关于boost 智能指针auto_ptr scoped_ptr shared_ptr scoped_array shared_array 总结的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



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

相关文章

HarmonyOS学习(七)——UI(五)常用布局总结

自适应布局 1.1、线性布局(LinearLayout) 通过线性容器Row和Column实现线性布局。Column容器内的子组件按照垂直方向排列,Row组件中的子组件按照水平方向排列。 属性说明space通过space参数设置主轴上子组件的间距,达到各子组件在排列上的等间距效果alignItems设置子组件在交叉轴上的对齐方式,且在各类尺寸屏幕上表现一致,其中交叉轴为垂直时,取值为Vert

学习hash总结

2014/1/29/   最近刚开始学hash,名字很陌生,但是hash的思想却很熟悉,以前早就做过此类的题,但是不知道这就是hash思想而已,说白了hash就是一个映射,往往灵活利用数组的下标来实现算法,hash的作用:1、判重;2、统计次数;

嵌入式QT开发:构建高效智能的嵌入式系统

摘要: 本文深入探讨了嵌入式 QT 相关的各个方面。从 QT 框架的基础架构和核心概念出发,详细阐述了其在嵌入式环境中的优势与特点。文中分析了嵌入式 QT 的开发环境搭建过程,包括交叉编译工具链的配置等关键步骤。进一步探讨了嵌入式 QT 的界面设计与开发,涵盖了从基本控件的使用到复杂界面布局的构建。同时也深入研究了信号与槽机制在嵌入式系统中的应用,以及嵌入式 QT 与硬件设备的交互,包括输入输出设

让树莓派智能语音助手实现定时提醒功能

最初的时候是想直接在rasa 的chatbot上实现,因为rasa本身是带有remindschedule模块的。不过经过一番折腾后,忽然发现,chatbot上实现的定时,语音助手不一定会有响应。因为,我目前语音助手的代码设置了长时间无应答会结束对话,这样一来,chatbot定时提醒的触发就不会被语音助手获悉。那怎么让语音助手也具有定时提醒功能呢? 我最后选择的方法是用threading.Time

git使用的说明总结

Git使用说明 下载安装(下载地址) macOS: Git - Downloading macOS Windows: Git - Downloading Windows Linux/Unix: Git (git-scm.com) 创建新仓库 本地创建新仓库:创建新文件夹,进入文件夹目录,执行指令 git init ,用以创建新的git 克隆仓库 执行指令用以创建一个本地仓库的

智能交通(二)——Spinger特刊推荐

特刊征稿 01  期刊名称: Autonomous Intelligent Systems  特刊名称: Understanding the Policy Shift  with the Digital Twins in Smart  Transportation and Mobility 截止时间: 开放提交:2024年1月20日 提交截止日

二分最大匹配总结

HDU 2444  黑白染色 ,二分图判定 const int maxn = 208 ;vector<int> g[maxn] ;int n ;bool vis[maxn] ;int match[maxn] ;;int color[maxn] ;int setcolor(int u , int c){color[u] = c ;for(vector<int>::iter

整数Hash散列总结

方法:    step1  :线性探测  step2 散列   当 h(k)位置已经存储有元素的时候,依次探查(h(k)+i) mod S, i=1,2,3…,直到找到空的存储单元为止。其中,S为 数组长度。 HDU 1496   a*x1^2+b*x2^2+c*x3^2+d*x4^2=0 。 x在 [-100,100] 解的个数  const int MaxN = 3000

状态dp总结

zoj 3631  N 个数中选若干数和(只能选一次)<=M 的最大值 const int Max_N = 38 ;int a[1<<16] , b[1<<16] , x[Max_N] , e[Max_N] ;void GetNum(int g[] , int n , int s[] , int &m){ int i , j , t ;m = 0 ;for(i = 0 ;

基于 YOLOv5 的积水检测系统:打造高效智能的智慧城市应用

在城市发展中,积水问题日益严重,特别是在大雨过后,积水往往会影响交通甚至威胁人们的安全。通过现代计算机视觉技术,我们能够智能化地检测和识别积水区域,减少潜在危险。本文将介绍如何使用 YOLOv5 和 PyQt5 搭建一个积水检测系统,结合深度学习和直观的图形界面,为用户提供高效的解决方案。 源码地址: PyQt5+YoloV5 实现积水检测系统 预览: 项目背景