stl和boost中智能指针使用总结

Boost库的智能指针shared_ptr剖析 之前的博客对Boost库的智能指针诞生的原因它们的作用,VS 和 VC下auto_ptr的不足,还解析了vc下的auto_ptr,以及Boost库的scoped_ptr和scoped_array这两个兄弟智能指针,可以查看之前的博客,今天我们直接入手shared_ptr。 shared_ptr简介 shared.ptr 是一个最像指针的“智能指针”,是boost.smart.ptr 库中最... 阅读详情

1. auto_ptr
auto_ptr主要是用来解决资源自动释放的问题,比如如下代码:
void Function()
{
Obj*p = new Obj(20);
...
if (error occor)
throw ... 或者 retrun;
delete p;
}
在函数遇到错误之后,一般会抛异常,或者返回,但是这时很可能遗漏之前申请的资源,及时是很有经验的程序员也有可能出现这种错误,
而使用auto_ptr会在自己的析够函数中进行资源释放。也就是所说的RAII
使用auto_ptr代码如下
void Function()
{
auto_ptr<Obj> ptr( new Obj(20) );
...
if (error occur)
throw exception...
}
这样无论函数是否发生异常,在何处返回,资源都会自动释放。
需要提一下的是这是一个被c++11标准废弃的一个智能指针,为什么会被废弃,先看一下下面的代码:
auto_ptr<Obj> ptr1( new Obj() );
ptr1->FuncA();
auto_ptr<Obj> ptr2 = ptr1;
ptr2->FuncA();
ptr1->FuncA();  // 这句话会异常
为什么在把ptr1复制给ptr2之后ptr1再使用就异常了呢?
这也正是他被抛弃的主要原因。
因为auto_ptr复制构造函数中把真是引用的内存指针进行的转移,也就是从ptr1转移给了ptr2,此时,ptr2引用了Obj内存地址,而ptr1引用的内存地址为空,、
此时再使用ptr1就异常了。


2. unique_ptr
unique_ptr可以看成是auto_ptr的替代品。因为他对对象的所有权比较专一,所以才叫unique 大笑
i) 无法进行复制构造和赋值操作
auto_ptr与unique_ptr的对比:
auto_ptr<Obj> ap(new Obj() );
auto_ptr<Obj> one (ap) ; // ok
auto_ptr<Obj> two = one; //ok


unique_ptr<Obj> ap(new Obj() );
unique_ptr<Obj> one (ap) ; // 会出错
unique_ptr<Obj> two = one; //会出错
也就是说unique_ptr对对象的引用比较专一,不允许随随便便的进行转移
ii)  可以进行移动构造和移动赋值操作
unique_ptr<Obj> GetObj()
{
unique<Obj> ptr( new Obj() );
return ptr;
}
unique<Obj> ptr = GetObj();
上面的代码可以顺利执行!
什么是移动构造和移动赋值呢? 这得益于C++11的标准规范。这个知识点可以参考参考网址中的第三个。
那么如果万一我就是需要把一个unique_ptr智能指针赋值给另外一个怎么办呢?
可以使用移动函数!如下:
unique<Obj> ptr1( new Obj() );
unique<Obj> ptr2( std::move(ptr1) );
这个效果和auto_ptr直接赋值是一样的,就是ptr1不再拥有Obj对象了,所以ptr1不能再用来操作内存中的Obj对象,因为这个是手动操作的,
所以程序员自己也会更加小心。


3. shared_ptr
auto_ptr和unique_ptr都只能一个智能指针引用对象,而shared_ptr则是可以多个智能指针同时拥有一个对象。
shared_ptr实现方式就是使用引用计数。这一技术在COM中是用来管理COM对象生命周期的一个方式。
引用计数的原理是,多个智能指针同时引用一个对象,每当引用一次,引用计数加一,每当智能指针销毁了,引用计数就减一,
当引用计数减少到0的时候就释放引用的对象。这种引用计数的增减发生在智能指针的构造函数,复制构造函数,赋值操作符,析构函数中。
这种方式使得多个智能指针同时对所引用的对象有拥有权,同时在引用计数减到0之后也会自动释放内存,也实现了auto_ptr和unique_ptr的资源释放的功能。


void Function()
 {
shared_ptr<Obj> ptr1( new Obj() ); // 引用计数为1
{
shared_ptr<Obj> ptr2( ptr1 ); // 引用计数为2
{
shared_ptr<Obj> ptr3 = ptr2; // 引用计数为3
int e = 0
}
//引用计数为2
}
//引用计数为1
}
//函数返回之后引用计数为0,new 出来的Obj内存已经释放了


由于shared_ptr支持复制构造,所以他可以作为标准库容器中的元素
vector<shared_ptr<Obj>> vect;
for (int i = 0; i < 10; ++i)
{
vect.push_back( shared_ptr<Obj>( new Obj() ) );
}
vector<shared_ptr<Obj>> vect2 = vect;
这些操作是auto_ptr和unique_ptr不能实现的。
注意,智能指针默认使用delete来释放资源,如果资源是FILE*怎么办?释放的时候就需要用fclose了。
如何实现呢? 
shared_ptr构造函数可以传递一个删除器。
FILE* pStm = fopen(...);
shared_ptr<FILE> fileRes(pStm, &fclose);
或者使用一个仿函数
class FileCloser { 
     public: 


        void operator()(FILE* file) { 


         std::cout << "The FileCloser has been called with a FILE*, " 


           "which will now be closed.\n"; 


         if (file!=0)  


           fclose(file); 


       } 


     }; 
shared_ptr<FILE> fileRes(pStm, FileCloser);
关于这点看一参考这篇文章: http://www.cnblogs.com/learn-my-life/p/3817151.html

4. weak_ptr


shared_ptr是一种强引用的关系,智能指针直接引用对象。那么这个会代码一个隐含的问题,就是循环引用,从而造成内存泄漏,即便是java语言有自己的
垃圾回收器,对这种内存泄漏也没有办法,所以循环引用对java程序员来说也是一个很值得注意的问题。首先来看一个循环引用的例子。


class Parent
{
public:
    shared_ptr<Child> child;
};




class Child
{
public:
    shared_ptr<Parent> parent;
};


void Function()
{
shared_ptr<Parent> pA(new Parent);
shared_ptr<Child> pB(new Child);
pA->child = pB;
pB->parent = pA;
}
现在来分析一下Function函数的执行过程:
1. 第一条语句使得pA引用了Parent一个指针,Parent引用计数为1
2. 第二条语句使得pB引用了Child一个指针,Child引用计数为1
3. 第三条语句,调用了shared_ptr<Child>类的赋值操作符,使得Child引用计数变为2
4. 第四条语句,调用了shared_ptr<Parent>类的赋值操作符,使得Parent引用计数变为2
5. 函数返回之前调用了shared_ptr<Parent>和shared_ptr<Child>类的析够函数,使得Child引用计数变为1,Parent引用计数变为1
看!函数执行完之后new出来的Parent和Child并没有释放,所以出现了内存泄漏。
出现泄漏的原因就是pA和pB相互引用了,导致两者所引用对象的引用计数不能减少到0,造成泄漏。
如果把第三条语句或者第四条语句任意删除一个,就不会有泄漏了。
这就是强引用所带来的问题。
weak_ptr从字面意思上可以看出是一个弱指针,不是说明这个指针的能力比较弱,而是说他对他所引用的对象的所有权比较弱,
说得更直接一点儿就是他并不拥有所引用对象的所有权,而且他还不能直接使用他所引用的对象。


在stl中,weak_ptr是和shared_ptr配合使用的,在实现shared_ptr的时候也就考虑了weak_ptr的因素。
weak_ptr是shared_ptr的观察者,它不会干扰shared_ptr所共享对象的所有权,
当一个weak_ptr所观察的shared_ptr要释放它的资源时,它会把相关的weak_ptr的指针设置为空,防止weak_ptr持有悬空的指针。
注意:weak_ptr并不拥有资源的所有权,所以不能直接使用资源。
可以从一个weak_ptr构造一个shared_ptr以取得共享资源的所有权。
void Function()
{
 shared_ptr<int> sp( new Obj() );
 assert(sp.use_count() == 1);
 weak_ptr<int> wp(sp); //从shared_ptr创建weak_ptr
 assert(wp.use_count() == 1);
 if (!wp.expired())//判断weak_ptr观察的对象是否失效
 {
  shared_ptr<int> sp2 = wp.lock();//获得一个shared_ptr
  *sp2 = 100;
  assert(wp.use_count() == 2);
 }
 assert(wp.use_count() == 1);
 return 0;
}
weak_ptr并没有重载-> 和 * 操作符,所以我们不能通过他来直接使用资源,我们可以通过lock来获得一个shared_ptr对象
来对资源进行使用,如果引用的资源已经释放,lock()函数将返回一个存储空指针的shared_ptr。 expired函数用来判断资源是否失效。
使用weak_ptr并不会增加资源的引用计数。所以对资源的引用是弱引用,利用这个特性可以解决前面所说的循环依赖问题。


class Parent
{
public:
    weak_ptr<Child> child;
};




class Child
{
public:
    weak_ptr<Parent> parent;
};


void Function()
{
shared_ptr<Parent> pA(new Parent);
shared_ptr<Child> pB(new Child);
pA->child = pB;
pB->parent = pA;
}


这个时候第三和第四条语句的执行并没有增加引用计数,从而在函数执行完成只有能自动释放内存。
从上面的分析可以看出,weak_ptr是一种辅助shared_ptr的一种智能指针,一般不单独使用,而是结合
shared_ptr一起使用。


总结:
1. 尽量使用unique_ptr而不要使用auto_ptr
2. 一般来说shared_ptr能够满足我们大部分的需求
3. weak_ptr可以避免递归的依赖关系

网址:
1. http://www.jellythink.com/archives/684
2. http://www.jellythink.com/archives/673
3. http://www.cnblogs.com/TianFang/archive/2013/01/26/2878356.html (c++右值引用相关知识点)
4. http://www.cnblogs.com/learn-my-life/p/3817151.html
5. http://blog.youkuaiyun.com/hp_truth/article/details/40511617
6. http://www.cppblog.com/deane/archive/2010/02/25/108428.html(c++临时对象相关知识点)
7. http://blog.youkuaiyun.com/mmzsyx/article/details/8090849
8. http://www.cnblogs.com/learn-my-life/p/3817279.html

 

5. boost库中scoped_ptr

scoped_ptr是boost库提供的很类似auto_ptr的智能指针,它包装了new操作符在堆上分配的动态对象,能够保证动态创建的对象在任何时候都可以被正确地删除。在实现上都是利用了一个栈上的对象去管理一个堆上的对象,从而使得堆上的对象随着栈上的对象销毁时自动删除。但scoped_ptr的所有权更加严格,不能转让,并且永远不能被复制或赋值,一旦scoped_ptr获取了对象的管理权,你就无法再从它那里取回来。
  因此,在实际编程中是使用scoped_ptr还是auto_ptr,就需要根据它们的不同点进行选择。如果,根据你的设计是否需要转移所有权。如果需要那么就使用auto_ptr,如果不需要那么就使用scoped_ptr。scoped_ptr是一种轻量级的智能指针;使用它不会使你的程序变大或变慢。它只会让你的代码更安全,更好维护。
 

参考文章:

【1】 https://www.cnblogs.com/lsgxeva/p/7668868.html

【2】 https://blog.youkuaiyun.com/huangjh2017/article/details/70141741 

C++:智能指针unique_ptr与vector;shared_ptr与vector 文章目录错误分析 错误 class abc { public: abc(){cout<<"construct"<<endl;} ~abc(){cout<<"destroy"<<endl;} }; int main() { vector<unique_ptr<abc>> v_s_a; unique_ptr<abc> u_s_b (new abc); v_s_a.push_back(u_s_b); 阅读详情

相关推荐

本地AI代码助手:智能解析大型代码库,实现自动化重构与理解

在软件开发中,大型代码库的理解与维护是常见挑战。传统方法依赖人工阅读和有限上下文工具,效率低下。通过结合检索增强生成(RAG)和多智能体(Multi-Agent)架构,现代AI工具能够智能解析代码结构,理解模块关系,并精准定位相关代码片段。这种技术不仅能提升代码探索效率,还能自动化执行重构、文档生成等任务,在遗留系统维护、快速上手新项目等场景中发挥关键作用。本文以blackboxaicode/cli为例,展示了如何利用其代码感知和Workflow Automation能力,高效处理复杂代码库。

weixin_30240349的博客 369

stl中auto_ptr,unique_ptr,shared_ptr,weak_ptr四种智能指针使用总结

在一次面试过程中被问到了stl中的四种智能指针的用法 由于经验不足,我只知道auto_ptr和shared_ptr,然后还说了一个弱... 然后面试官就提示是weak_ptr,之后他又主动说出了unique_ptr 我也只对auto_ptr和shared_ptr做了一下使用场景。 现在回想起来,对这次面试还是很不满意,对自己的知识面也是很不满意,最近工作不是很忙,专门来总结一下这四种智

最快的脚步不是跨越,而是继续;最慢的步伐不是缓慢,而是徘徊! 6669

Ubuntu 22.04远程桌面终极指南:从零配置RDP到解决黑屏问题

本文提供了一份Ubuntu 22.04远程桌面配置的终极指南,详细讲解了如何从零开始安装和配置RDP服务,并重点解决了连接后常见的黑屏问题。通过分析会话冲突、修复启动脚本及配置权限策略,帮助用户实现稳定、高效的远程桌面连接,优化分辨率、禁用锁屏,打造无缝的远程工作体验。

sony5的博客 1386

理解智能指针(Smart Pointer)

智能指针(smart ponter)是一项十分巧妙的C++编程技术,现在已经发展得相当成熟,运用也相当广泛。你一定对STL中的auto_ptr、shared_ptr毫不陌生,它们就是智能指针的具体实现。本文并不会详解auto_ptr和shared_ptr的语法,你可以在MSDN中轻轻松松查到,本文将主要分析智能指针的意义以及运用auto_ptr和shared_ptr的注意事项。 想一想那些没有智

btwsmile's blog 2549

2.4G跳频算法 2.4G切信道算法 (简例示意nRF52832)

2.4G跳频算法 nRF52832示例 2.4G自适应信道算法

Peter.Min 958

Langchain4j 文档处理实战:从加载到分割的完整流程解析

本文详细解析了使用Langchain4j进行文档处理的完整流程,涵盖从文档加载、解析到分割的核心步骤。通过实战代码示例,重点介绍了如何利用文档分割器将大文档切割为适合大语言模型处理的片段,并提供了参数调优与避坑指南,帮助Java开发者高效构建AI应用的数据处理基础。

smartcontract5的博客 543

weak_ptr智能指针

为什么需要weak_ptr? 因为虽然我们可以使用shared_ptr指针,但是不得不说使用shared_ptr还有一些不美好的地方需要注意和解决,所以我们的weak_ptr也是为了帮助解决这些问题而设计出来的。 问题如下: 环向指向:两个共享指针之间互相指向,所以就永远也不会出现计数器减为0的情况出现所以,就不会释放资源。 想共享但是不愿意拥有:比如说引用的寿命其实比引用的对象存活时间长...

weixin_42427338的博客 375

ksz9031 mmd读取不了_ZYNQ. LwIP.PHY.KSZ9031RNX

新一块板子米尔科技的z-turn 使用的PHY芯片是Micrel的 KSZ9031RNX 而不是zedboard上的Marvell的。直接使用lwip的echo server demo时会报错 , 无法启动。在网上找了很久终于找到几篇关于这个问题的文章。修改PHY的驱动xemacpsif_physpeed.c文件该芯片的PHY Identifier 是 0x0022bsp设置中修改参数以提速MEM...

weixin_39626298的博客 925

stl智能指针和boost智能指针对比

先说说stl中的智能指针auto_ptr,先说说auto_ptr的特点。std::auto_ptr用来管理单个堆内存对象,但是独享所有权,且不允许赋值和拷贝(没有重载operator=),所以如果在函数内部需要指针时,auto_ptr是一个不错的选择,但需要注意的是它不容许复制,这也就是容器(vector,list等)中的元素类型不能是auto_ptr。一般的用法是 std::auto_ptr

繁华落尽梦一场 3355

Qualcomm 常用NV列表

^ NV ITEM ^ 功能^^ |NV10 |mode prefer,找网模式|新平台使用NV80000| ^NV74 NV74=0关闭自动接听电话^ |NV240 |NV240=FALSE|EVDO出现网络的问题,此项必须设定为FALSE| |NV255 |CDMA规避网络列表(SID/NID号)| |NV256 |

sdrgtywretyeruet的专栏 5776

头歌OpenGauss数据库-G.视图的使用

OpenGauss数据库-G.视图的使用

python一生之敌的博客 1385

Boost和STL的几种智能指针

实际中没有多少人用

dreamcs的专栏 2190

使用ArcGIS Pro进行土地利用分类的机器学习与深度学习

传统的土地利用分类方法通常依赖于手动解译和规则定义,但随着机器学习和深度学习的发展,我们现在可以利用这些技术来自动化和提高分类的精度。ArcGIS Pro是一种功能强大的GIS软件,它提供了丰富的工具和功能,可以支持土地利用分类的机器学习和深度学习。我们将首先讨论数据准备和预处理的步骤,然后介绍常用的机器学习和深度学习方法,并提供相应的源代码示例。这可以通过人工标注或半自动的方式完成。数据裁剪:根据研究区域的范围,裁剪遥感影像数据,以减少计算和存储的负担,并确保只包含感兴趣的土地利用区域。

code_program481的博客 2040

智能指针概念和使用

目录结构: 一 通过案例引入智能指针 二 智能指针的作用 三 设计辅助类实现智能指针作用 四 设计类模板实现智能指针作用 五 使用stl和boost提供的标准智能指针类模板处理问题 一 通过案例引入智能指针 有如下的程序: #include using namespace std; class exam { public: exam(int *p):ptr§{} exam(exam &o...

黄土塬 328

锂电池充电器电路设计 里面有电路

锂电池充电器电路设计 里面有电路 3.7V升压到5V电路设计。

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

改进C++程序的重剑stl库和战斧boost库

改进C++程序的重剑stl库和战斧boost库 改进C++程序的重剑stl库和战斧boost库分类:游戏编程之——通用编程2009-02-23 19:081449人阅读评论(1)收藏举报改进C++程序的重剑stl库和战斧boost库...

108

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

C++ STL与Boost库选型指南:资深工程师的实战经验总结

在C++开发中,标准模板库(STL)和Boost库是两大核心工具集,理解它们的定位差异对项目技术选型至关重要。STL作为C++标准的一部分,提供了容器、算法和迭代器等基础组件,具有极佳的可移植性和性能,是构建可靠软件的首选。其设计遵循最小化和正交化原则,确保了代码的稳定性和跨平台一致性。相比之下,Boost库则扮演着前沿试验场的角色,提供了智能指针、文件系统操作和异步I/O等扩展功能,许多特性后来被纳入C++标准。从工程实践角度看,合理选择工具能显著提升开发效率和代码质量。例如,在内存管理场景中,C++11

weixin_33910385的博客 374

终极指南:Boost与STL对比分析,何时选择最佳C++库解决方案

在C++开发中,标准模板库(STL)和Boost库都是不可或缺的工具。Boost作为STL的扩展和补充,提供了更多高级功能和实用组件,而STL则是C++标准的核心组成部分。本文将深入对比两者的优缺点,帮助开发者在不同场景下做出最佳选择,轻松掌握C++库的使用技巧。 ## 一、STL:C++标准的基石 STL(Standard Template Library)是C++标准的重要组成部分,包含了

gitblog_00007的博客 512

boost库基本简介

Boost是一个功能强大、构造精巧、跨平台、开源并且完全免费的C++程序库,有着“C++‘准’标准库”的美誉。 它由C++标准委员会部分成员所设立的Boost社区开发并维护,使用了许多现代C++编程技术,内容涵盖字符串处理、正则表达式、容器与数据结构、并发编程、函数式编程、泛型编程、设计模式实现等许多领域,极大地丰富了C++的功能和表现力,能够使C++软件开发更加简洁、优雅、灵活和高效。 ...

haimianjie2012的专栏 1299

Boost练习程序(智能指针)

#include <iostream>#include <vector>#include <string>#include <boost/shared_ptr.hpp>class A{public: A(std::string s){a=s;} std::string a; void print(){std::cout<&...

weixin_34107955的博客 992

Boost和STL学习资料大全

Boost 库学习指南 Boost 中文站 Boost库是一个经过千锤百炼、可移植、提供源代码的C++库,作为标准库的后备,是C++标准化进程的发动机之一。 Boost库由C++标准委员会库工作组成员发起,在C++社区中影响甚大,其成员已近2000人。 Boost库为我们带来了最新、最酷、最实用的技术,是不折不扣的“准”标准库。本站主要介绍Boost相关的中文技术文档。 Boo

liuyinghui523的专栏 673

有效的使用和设计COM智能指针——条款3:按照功能和实现原理选择合适的智能指针

条款3:按照功能和实现原理选择合适的智能指针 更多条款请前往原文出处:http://blog.youkuaiyun.com/liuchang5 智能指针种类繁多,从实现原理上可以划分为“基于所有权传递”和“基于引用计数”两大类。C++中内置的std::auto_ptr则为“基于所有权

liuchang5的专栏 1664

C++智能指针

** 前言** C++ 标准模板库 STL(Standard Template Library) 一共给我们提供了四种智能指针:auto_ptr、unique_ptr、shared_ptr 和 weak_ptr,其中 auto_ptr 是 C++98 提出的,C++11 已将其摒弃,并提出了 unique_ptr 替代 auto_ptr。虽然 auto_ptr 已被摒弃,但在实际项目中仍可使用,但建议使用更加安全的 unique_ptr,后文会详细叙述。shared_ptr 和 weak_ptr 则是 C+

GreedySnaker的博客 924

boost智能指针小结

 1.STL的指针auto_ptr当拷贝构造或者赋值时会发生控制权的转移,所以不能被当做元素存储到数组或者标准库的容器中去,当然也不能用指向数组的指针去初始化一个auto_pt对象。下面介绍几个此类的几个关键方法。ap.reset(p);  如果p与ap的值不相同,则删除ap指向的对象并且将ap绑定到p。ap.release(); 返回ap所保存的指针并且使ap成为未绑定的。ap.

1781

stl,boost,thread,IOCP,socket

1> STL学习 1 2 >boost asio asio,一个跨平台的支持异步I/O的网络通讯socket库 2 3>模板 2 4>boost timer 3 5>shared_ptr 3 6>Oracle 表数据的C++存取接口 occi 3 7>多线程编程 4 8>STL例子 10 8>socket编程 22 9> IOCP编程 23 10.面向对象的static关键

xucheng104的专栏 2365

【Boost】系列02:内存管理之scoped_ptr智能指针

智能指针,stl中有auto_ptr,boost的smart_ptr库有6种: scoped_ptr,scoped_array,shared_ptr,shared_array,weak_ptr和intrusive_ptr. scoped_ptr的拷贝构造函数和赋值操作符声明为私有,以禁止对智能指针的复制。 例1: #include <boost/smart_ptr.hpp>...

weixin_30300523的博客 66
上一篇: 高效计算N次方
下一篇: 《STL源码剖析》相关面试题总结
Poo_Chai
博客等级 码龄9年 178粉丝 117原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值