C++智能指针之auto_ptr

C++:智能指针(1)——auto_ptr, unique_ptr的区别 正在上传…重新上传取消 auto_ptr, unique_ptr 首先看一段代码 #include <iostream> #include <type_traits> #include <vector> #include <memory> #include <exception> using namespace std; int... 阅读详情
1. auto_ptr
auto_ptr 是C++标准库提供的类模板,auto_ptr对象通过初始化指向由new创建的动态内存,它是这块内存的拥有者,一块内存不能同时被分给两个拥有者。当auto_ptr对象生命周期结束时,其析构函数会将auto_ptr对象拥有的动态内存自动释放。即使发生异常,通过异常的栈展开过程也能将动态内存释放。auto_ptr不支持new 数组。

2. auto_ptr需要包含的头文件
#include <memory>

3. 初始化auto_ptr对象的方法

1) 构造函数
1] 将已存在的指向动态内存的普通指针作为参数来构造
int* p = new int(33);
auto_ptr<int> api(p);

2] 直接构造智能指针
auto_ptr< int > api( new int( 33 ) );

2) 拷贝构造
利用已经存在的智能指针来构造新的智能指针
auto_ptr< string > pstr_auto( new string( "Brontosaurus" ) );
auto_ptr< string > pstr_auto2( pstr_auto );  //利用pstr_auto来构造pstr_auto2
因为一块动态内存智能由一个智能指针独享,所以在拷贝构造或赋值时都会发生拥有权转移的过程。
在此拷贝构造过程中,pstr_auto将失去对字符串内存的所有权,而pstr_auto2将其获得;对象销毁时,pstr_auto2负责内存的自动销毁。

3) 赋值
利用已经存在的智能指针来构造新的智能指针
auto_ptr< int > p1( new int( 1024 ) );
auto_ptr< int > p2( new int( 2048 ) );
p1 = p2;

在赋值之前,由p1 指向的对象被删除。赋值之后,p1 拥有int 型对象的所有权。该对象值为2048。 p2 不再被用来指向该对象。 

4. 空的auto_ptr
通常的指针在定义的时候若不指向任何对象,我们用Null给其赋值。对于智能指针,因为构造函数有默认值0,我们可以直接定义空的auto_ptr如下:
auto_ptr< int > p_auto_int;  //不指向任何对象

5. 防止两个auto_ptr对象拥有同一个对象(一块内存)
因为auto_ptr的所有权独有,所以下面的代码会造成混乱。

int* p = new int(0);
auto_ptr<int> ap1(p);
auto_ptr<int> ap2(p);

因为ap1与ap2都认为指针p是归它管的,在析构时都试图删除p, 两次删除同一个对象的行为在C++标准中是未定义的;所以我们必须防止这样使用auto_ptr。  

6. 警惕智能指针作为参数
1) 按值传递时,函数调用过程中在函数的作用域中会产生一个局部对象来接收传入的auto_ptr(拷贝构造),这样,传入的实参auto_ptr就失去了其对原对象的所有权,而该对象会在函数退出时被局部auto_ptr删除。如下例:
void f(auto_ptr<int> ap)
{cout<<*ap;}
auto_ptr<int> ap1(new int(0));
f(ap1);
cout<<*ap1; //错误,经过f(ap1)函数调用,ap1已经不再拥有任何对象了。

2) 引用或指针时,不会存在上面的拷贝过程。但我们并不知道在函数中对传入的auto_ptr做了什么,如果当中某些操作使其失去了对对象的所有权,那么这还是可能会导致致命的执行期错误。
结论:const reference是智能指针作为参数传递的底线

7. auto_ptr不能初始化为指向非动态内存
原因很简单,delete 表达式会被应用在不是动态分配的指针上这将导致未定义的程序行为。

8. auto_ptr常用的成员函数
1) get()
返回auto_ptr指向的那个对象的内存地址。如下例:
int* p = new int(33);
cout << "the adress of p: "<< p << endl;
auto_ptr<int> ap1(p);
cout << "the adress of ap1: " << &ap1 << endl;
cout << "the adress of the object which ap1 point to: " << ap1.get() << endl;
输出如下:
the adress of p: 00481E00
the adress of ap1: 0012FF68
the adress of the object which ap1 point to: 00481E00
第一行与第三行相同,都是int所在的那块内存的地址。第二行是ap1这个类对象本身所在内存的地址。

2) reset()
重新设置auto_ptr指向的对象。类似于赋值操作,但赋值操作不允许将一个普通指针指直接赋给auto_ptr,而reset()允许。如下例:
auto_ptr< string > pstr_auto( new string( "Brontosaurus" ) );
pstr_auto.reset( new string( "Long -neck" ) );
在例子中,重置前pstr_auto拥有"Brontosaurus"字符内存的所有权,这块内存首先会被释放。之后pstr_auto再拥有"Long -neck"字符内存的所有权。
注:reset(0)可以释放对象,销毁内存。

3) release()
返回auto_ptr指向的那个对象的内存地址,并释放对这个对象的所有权。
用此函数初始化auto_ptr时可以避免两个auto_ptr对象拥有同一个对象的情况(与get函数相比)。
例子如下:
auto_ptr< string > pstr_auto( new string( "Brontosaurus" ) );
auto_ptr< string > pstr_auto2( pstr_auto.get() ); //这是两个auto_ptr拥有同一个对象,在释放对象时,会出现未定义行为
auto_ptr< string > pstr_auto2( pstr_auto.release() ); //release可以首先释放所有权 


示例
#include <iostream>
#include <memory>

using namespace std;

struct A
{
        explicit A(string str){m_str = str; cout << m_str << " : constructor~~" << endl; }
        ~A(){cout << m_str << " : deconstructor~~~" << endl;}
        void outmsg(){cout << "outmsg : "+m_str << endl;}
        private:
        string m_str;
};
int main()
{
        auto_ptr<A> aptr (new A(string("auto")));
        aptr.get()->outmsg();
        aptr.reset(new A(string("msg")));
        auto_ptr<A> aptr2 (aptr.release());
        //auto_ptr<A> aptr2 (aptr.get());  //出现段错误,这是由于aptr和aptr2指向了同一个对象,出现了重复释放的问题  double free or corruption (fasttop)
}

执行结果:
auto : constructor~~
outmsg : auto
msg : constructor~~
auto : deconstructor~~~
msg : deconstructor~~~
c++智能指针的创建 c++智能指针的创建 c及c++中的指针是很麻烦的 所以现在有很多技巧去减少问题的出现。 欢迎大家给出意见。 立即下载

相关推荐

深入浅出DNS系列(一)- DNS杂谈

黄丝玛:班达山,你好,我记性不好,你告诉我搜狐、新浪的网站IP地址好吗? 班达山:你问问DNS先生吧,他专门干这买卖的

jiangsd198的博客 4129

vc 下和Linux 下的auto_ptr源码剖析

1.vc template<class_Ty> classauto_ptr { public: typedef_Tyelement_type; auto_ptr(_Ty*_P=0) :_Owns(_P!=0),_Ptr(_P) {} //拷贝构造将_Y的管理权_Owns=false释放后将指针赋值过去 auto_ptr(...

weixin_34306446的博客 117

NuPlayer 之 Renderer

触发postDrainAudioQueue_l()或postDrainVideoQueue()开始渲染。解码器输出数据 → NuPlayer::Decoder::onMessageReceived。音频数据存入mAudioQueue,视频数据存入mVideoQueue。• 每次写入后通过mNotifyConsumed通知解码器。• 通过AudioSink::write()写入音频设备。• 根据VSync信号和音频时钟调整渲染时机。• 通过Surface直接提交给显示系统。

aningxiaoxixi的博客 304

linux有智能指针吗,三种智能指针的使用与区别

在编写程序的过程中常常不注意就会弄出很多的野指针。今天看了看总结了一下三种智能指针(auto_ptr、shared_ptr与unique_ptr)的用法与区别。如有错误与不成熟的见解请一定指正。指针使用完毕后会使用delete回收内存,但刚刚入门的小白往往会忽略这一语句,但即使在代码末尾添加了delete也不一定会起到作用,例如:void demo(string &str){string ...

weixin_39756481的博客 306

哈工大OS实验四——进程运行轨迹的跟踪与统计

进程运行轨迹的跟踪与统计 进程从创建(Linux 下调用 fork())到结束的整个过程就是进程的生命期,进程在其生命期中的运行轨迹实际上就表现为进程状态的多次切换,如进程创建以后会成为就绪态;当该进程被调度以后会切换到运行态;在运行的过程中如果启动了一个文件读写操作,操作系统会将该进程切换到阻塞态(等待态)从而让出 CPU;当文件读写完毕以后,操作系统会在将其切换成就绪态,等待进程调度算法来调度该进程执行…… process.c解读 void cpuio_bound(int last, int cpu_

优快云-ych 1001

Cisco Firepower FMCv修改管理Ip方法

Cisco Firepower FMCv修改管理Ip方法

funnycoffee123的博客 1091

linux版vs,VS/Linux版的auto_ptr

1、VC版智能指针上次的对其auto_ptr内部结构的实现有些问题:(1)、赋值语句auto_ptr&operator=(constauto_ptr&_Y){if(this!=&_Y){if(_Ptr!=_Y._Ptr){if(_Owns)delete_Ptr;_Owns=_Y._Owns;}elseif(_Y._Owns){//这个地方上次写错...

weixin_39801356的博客 178

【DaVinci Configurator专题】-2-将CAN 2.0或CANFD Matrix的Arxml/DBC文件导入到CFG

共9页 目录 1 打开DaVinci Configurator,导入Arxml文件 2 解决导入Arxml文件后可能会出现的一些错误 3 验证CFG的配置 4 根据CFG的配置生成代码 5 结尾 <--返回「实战篇」博文-总目录--> <--返回「Autosar从入门到精通-实战篇」专栏主页--> 关键词: Open the Input Files Assistant Complete update process Update ECU configurati

「汽车电子助手」的博客 6123

智能指针auto_ptr

智能指针(auto_ptr) 这个名字听起来很酷是不是?其实auto_ptr 只是C++标准库提供的一个类模板,它与传统的new/delete控制内存相比有一定优势,但也有其局限。本文总结的8个问题足以涵盖auto_ptr的大部分内容。 1. auto_ptr是什么? auto_ptr 是C++标准库提供的类模板,auto_ptr对象通过初始化指向由new创建的动态内存,它是这块内存的拥有

arhaiyun的专栏 1187

vue2学习笔记2-老规矩,从Hello World开始,了解Vue实例和模板

想要把“Hello,World”放置在页面上,首先需要准备一个HTML的块级元素div,来承接内容。

l_q_l的专栏 1256

AI上推荐 之 NeuralCF与PNN模型(改变特征交叉方式)

1. 前言 随着信息技术和互联网的发展, 我们已经步入了一个信息过载的时代,这个时代,无论是信息消费者还是信息生产者都遇到了很大的挑战: 信息消费者:如何从大量的信息中找到自己感兴趣的信息? 信息生产者:如何让自己生产的信息脱颖而出, 受到广大用户的关注? 为了解决这个矛盾, 推荐系统应时而生, 并飞速前进,在用户和信息之间架起了一道桥梁,一方面帮助用户发现对自己有价值的信息, 一方面让信息能够展现在对它感兴趣的用户前面。 推荐系统近几年有了深度学习的助推发展之势迅猛, 从前深度学习的传统推荐模型(协

Miracle8070 1万+

C++的智能指针auto_ptr、unique_ptr源码解析

C++的智能指针auto_ptr、unqiue_ptr源码解析1、前言2、源码准备3、源码解析3.1、auto_ptr解析3.2、unqiue_ptr解3.3、unqiue_ptr的一个偏特化版本4、智能指针相关内容的总结5、总结 1、前言 本文仅对C++智能指针auto_ptr、unqiue_ptr源码进行解析,需要读者有一定的C++基础并且对智能指针有所了解,本文并不对智能指针的使用方法、使用场景、效率等方面进行阐述分析,这些知识需自行查阅相关书籍去了解。 建议大家先看一下这篇文章《C++11的智能指

游戏行业资深搬砖人员 3425

Oracle 从入门到精通系列(入门篇)1.1-Oracle 数据库发展史

Oracle 从入门到精通系列(入门篇)1.1-Oracle 数据库发展史

LuciferLiu_DBA 2190

【C++入门到精通】智能指针 auto_ptr、unique_ptr简介及C++模拟实现 [ C++入门 ]

这篇文章介绍了 C++ 中的两种智能指针:std::auto_ptr和std::unique_ptr。首先,文章简要介绍了它们的作用和使用示例。然后,对于std::auto_ptr,文章展示了一个简单的模拟实现,解释了每个函数的作用和实现原理。接着,文章介绍了更为严格的 std::unique_ptr,包括其特点、使用示例和模拟实现。对于模拟实现,文章详细解释了如何防止拷贝和赋值,并提供了两种不同的思路。整篇文章内容清晰明了,对于想要学习 C++ 动态内存管理的读者具有很好的参考价值。

Yawesh的博客 2727

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

【C++】智能指针——auto_ptr,unique_ptr,shared_ptr

1.智能指针对象中引用计数是多个智能指针对象共享的,两个线程中智能指针的引用计数同时 ++或--,这个操作不是原子的,引用计数原来是1,++了两次,可能还是2.这样引用计数就错 乱了。旧的智能指针的会转移给新的智能指针,而旧的智能指针的会被置空。解决方案:在引用计数的场景下,把节点中的_prev和_next改成weak_ptr就可以了,weak_ptr不会增加引用计数,代码示意。该问题是有类似于链表节点的结构引起的,当外部的智能指针都释放了,就拿不内部的智能指针,那么节点就不会释放。使用方法参考官方文档。

2301_79796701的博客 1842

efm32 入门.pdf

本PDF共计22页,介绍的是操作驱动API,下载与否自己斟酌。

C++智能指针的使用,auto_ptr,unique_ptr,shared_ptr,weak_ptr详解

C++智能指针的用法,auto_ptr,unique_ptr,shared_ptr,weak_ptr

liu20000505的博客 2313

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

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

C++ auto_ptr智能指针的用法

C++ auto_ptr智能指针的用法

愤怒的小狐狸----博客专栏 3万+

C++智能指针auto_ptr、unique_ptr、shared_ptr、weak_prt详解

C++智能指针auto_ptr、unique_ptr、shared_ptr、weak_prt详解

GodFishhh的博客 2467

cpp11新特性之智能指针(上):关于auto_ptr的一切

今天,我想和大家讨论一个已被淘汰的智能指针——auto_ptr。我们将从它的使用方法、内部源码分析、存在的缺陷,到常见的陷阱几个方面进行深入探讨,以彻底把握智能指针的核心逻辑。这不仅为我们后续学习 shared_ptr、unique_ptr 以及 weak_ptr 打下了坚实的基础,而且通过理解其需求和不足,我们能更加深刻地体会智能指针设计背后的理念,使得我们在使用它们时更加得心应手。

大龄工科菜鸡的cpp修行之路 2301

C++ 智能指针的原理:auto_ptr、unique_ptr、shared_ptr、weak_ptr

介绍C++的智能指针:auto_ptr、unique_ptr、shared_ptr、weak_ptr。介绍了每种智能指针的作用和特点,以及它们的实现原理,同时介绍了shared_ptr的循环引用的问题,以及如何解决循环引用。

weixin_57761086的博客 2522

C++ 浅谈之智能指针 auto_ptr 和 unique_ptr 对比

智能指针 auto_ptr 和 unique_ptr 对比

优质后端技术知识记录 821

C++智能指针——auto_ptr详解

前言 从之前智能指针的介绍中可以了解到智能指针主要作用是管理内存,避免内存泄漏和悬垂指针。 之前介绍的不管是智能指针与引用计数详解还是智能指针与句柄详解,其核心就是通过一个类来管理被new出来的对象,具体的技术就是靠引用计数。 auto_ptr介绍 auto_ptr的实现原理其实就是RAII,在构造的时候获取资源,在析构的时候释放资源,并进行相关指针操作的重载,使用起来就像普通的指针。该智能指针已...

yj_android_develop的博客 1万+

【c++】智能指针(auto_ptr, unique_ptr, shared_ptr, weak_ptr)

前言 一、为什么需要智能指针 二、智能指针 RAII 像指针一样使用 三、auto_ptr 概念讲解 模拟实现 测试 四、unique_ptr 概念讲解 模拟实现 测试 五、shared_ptr 概念讲解 模拟实现 测试 六、shared_ptr的循环引用 场景引入 如何解决循环引用问题 七、weak_ptr 概念讲解 模拟实现 测试 八、shared_ptr的定制删除器 概念讲解 模拟实现 测试一 测试二 测试三 测试四 九、智能指针的总结 十、内存泄漏 概念讲解 内存泄漏分类 如何检测内存泄漏 如何避免

重铸自身根基的博客 1621

c++智能指针(2) -- auto_ptr

auto_ptr 名称(new 空间),// 类型: 智能指针指向的类型,空间:智能指针管理的空间// 创建一个p1的智能指针对象,其指向int类型的数据,动态开辟一个int类型的空间作为参数(其内部的指针会指向这片空间)// 创建一个空对象,指向int类型的数据,其内部的指针会指向NULL。

weixin_68026222的博客 1328

C++智能指针auto_ptr

简单来说,智能指针是一个自定义的类型,智能指针对象中包含一个指针,此指针指向动态开辟的空间,在智能指针对象离开作用域后,析构函数会自动调用删除器(Deleter,auto_ptr不具备删除器),释放所申请的资源。这种设计思想来源于RAII(Resource acquisition is initialization),它充分利用了C++语言局部对象自动销毁的特性来控制资源的生命周期。

Singularitys123的博客 420
上一篇: RTTI和类型转换
下一篇: boost.any实现任意类型存储
IT_Linux
博客等级 码龄14年 31粉丝 77原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值