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++中的指针是很麻烦的 所以现在有很多技巧去减少问题的出现。 欢迎大家给出意见。 立即下载

相关推荐

服务器被矿工入侵记录

一次服务器被矿工入驻的处理记录

王瑞的技术专栏 1332

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

保姆级教程:在RK3576上配置USB网卡从零到外网访问(附udev规则详解)

本文提供了在RK3576开发板上配置USB网卡的完整教程,涵盖从内核驱动、udev规则到网络路由的全流程。重点讲解了如何利用USB Gadget功能实现高速网络连接,并构建稳定的算力集群,确保多设备间通信及外网访问。

grass的博客 457

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

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

weixin_39756481的博客 306

因果推断--PSM的原理和应用(二)

上一篇介绍了DID,本文介绍和DID可一起搭配使用的一种因果推断方法PSM。在正式介绍PSM之前,先来简单回顾一下为什么需要因果推断以及如何做因果推断。我们都知道相关非因果,比起相关我们更希望知道两个事件之间的因果关系,有了确切的因果关系,才能知道对A如何操作才能引起B的变化。解决因果推断问题,目前主要有两种框架,Rubin虚拟事实模型和Pearl因果图模型。站在数据分析的角度上,Rubin虚拟事实模型更容易理解,其核心思想是寻找恰当的对照组。

baidu_26137595的博客 1万+

Materials Studio实战技巧(八)——利用片段库高效构建有机金属配合物

本文详细介绍了在Materials Studio中利用Fragment Browser(片段浏览器)高效构建有机金属配合物的实战技巧。通过调用预置的Metal Templates和Ligands库,用户可以快速搭建如茂金属催化剂等复杂分子骨架,并利用对称性操作精确控制Meso与Rac构型。文章还涵盖了自定义片段库的创建与使用,能显著提升建模效率,适用于计算化学与材料模拟领域的研究者。

wine的专栏 936

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

解放双手:用KUKA示教器白键一键触发复杂工艺,自定义你的快捷指令

本文详细介绍了如何利用KUKA示教器的工艺白键功能,通过自定义快捷指令一键触发复杂工艺,显著提升自动化产线效率。文章涵盖UserTech技术栈解析、KRL脚本封装、人机交互视觉工程及工业实战策略,帮助工程师实现机械臂操作的高阶优化。

weixin_30379531的博客 432

智能指针auto_ptr

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

arhaiyun的专栏 1188

08-SD卡-TF卡硬件电路设计

SD卡-TF卡硬件电路设计

weixin_66510961的博客 8258

Python爬虫实战:基于Scrapy与Playwright高效爬取人民网新闻数据

本文将详细介绍如何使用Python最新技术栈(Scrapy框架结合Playwright浏览器自动化工具)高效爬取人民网新闻数据。文章包含完整项目搭建、反反爬策略、数据解析存储以及性能优化等核心内容,提供可直接运行的代码示例,适合中高级Python开发者学习现代网络爬虫开发技术。python# 去除特殊空白字符。

2201_76125261的博客 1118

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

基于 Simulink 的单相 PWM 整流器(四象限变流器)在高铁辅助电源系统中的建模与仿真实战教程

这是一份基于 Simulink 的实战教程。在高铁牵引供电与辅助电源系统中,单相 PWM 整流器(又称四象限变流器,4QC)是极其核心的“绿色电源”枢纽。传统的二极管整流器虽然结构简单,但会导致严重的输入电流畸变和低功率因数,对电网造成极大的谐波污染。而 PWM 整流器通过高频主动控制,不仅能将单相交流电转换为平稳的直流电,还能实现输入电流正弦化、单位功率因数(PF=1)运行,并支持能量双向流动(如列车再生制动时的能量回馈)。本教程将带你从数学模型出发,搭建一套高性能的电压电流双闭环控制系统。

amy_mhd的博客 47

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

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

Yawesh的博客 2727

STM32F407中文手册

STM32f407中文手册 本参考手册面向应用开发人员,提供有关使用 STM32F405xx/07xx、STM32F415xx/17xx、 STM32F42xxx 和 STM32F43xxx 微控制器存储器与外设的完整信息。STM32F405xx/07xx、STM32F415xx/17xx、STM32F42xxx 和 STM32F43xxx 构成一个微 控制器系列,各产品具有不同的存储器大小、封装和外设。有关订购信息以及器件的机械与电气特性,请参见数据手册。有关 ARM Cortex™-M4F 内核的信息,请参见《Cortex™-M4F 技术参考手册》。

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

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

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

2301_79796701的博客 1842

数学建模模型总结

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

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

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

liu20000505的博客 2313

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

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的博客 2468

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的定制删除器 概念讲解 模拟实现 测试一 测试二 测试三 测试四 九、智能指针的总结 十、内存泄漏 概念讲解 内存泄漏分类 如何检测内存泄漏 如何避免

重铸自身根基的博客 1622

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、付费专栏及课程。

余额充值