关于std:auto_ptr

很多人听说过标准auto_ptr智能指针机制,但并不是每个人都天天使用它。这真是个遗憾,因为auto_ptr优雅地解决了C++设计和编码中常见的问题,正确地使用它可以生成健壮的代码。本文阐述了如何正确运用auto_ptr来让你的代码更加安全——以及如何避免对auto_ptr危险但常见的误用,这些误用会引发间断性发作、难以诊断的bug。

1.为什么称它为“自动”指针?
auto_ptr只是众多可能的智能指针之一。许多商业库提供了更复杂的智能指针,用途广泛而令人惊异,从管理引用的数量到提供先进的代理服务。可以把标准C++ auto_ptr看作智能指针的Ford Escort(elmar注:可能指福特的一种适合家居的车型):一个简易、通用的智能指针,它不包含所有的小技巧,不像专用的或高性能的智能指针那么奢华,但是它可以很好的完成许多普遍的工作,它很适合日常性的使用。

auto_ptr所做的事情,就是动态分配对象以及当对象不再需要时自动执行清理。这里是一个简单的代码示例,没有使用auto_ptr所以不安全:
    // 示例 1(a): 原始代码
    //
    void f()
    {
      T* pt( new T );

      /*...更多的代码...*/

      delete pt;
    }

我们大多数人每天写类似的代码。如果f()函数只有三行并且不会有任何意外,这么做可能挺好的。但是如果f()从不执行delete语句,或者是由于过早的返回,或者是由于执行函数体时抛出了异常,那么这个被分配的对象就没有被删除,从而我们产生了一个经典的内存泄漏。

能让示例1(a)安全的简单办法是把指针封装在一个“智能的”类似于指针的对象里,这个对象拥有这个指针并且能在析构时自动删除这个指针所指的对象。因为这个智能指针可以简单的当成一个自动的对象(这就是说,它出了作用域时会自动毁灭),所以很自然的把它称之为“智能”指针:

    // 示例 1(b): 安全代码, 使用了auto_ptr
    //
    void f()
    {
      auto_ptr<T> pt( new T );

      /*...更多的代码...*/

    } // 酷: 当pt出了作用域时析构函数被调用,
      // 从而对象被自动删除

现在代码不会泄漏T类型的对象,不管这个函数是正常退出还是抛出了异常,因为pt的析构函数总是会在出栈时被调用。清理会自动进行。

最后,使用一个auto_ptr就像使用一个内建的指针一样容易,而且如果想要“撤销”资源,重新采用手动的所有权,我们只要调用release():

    // 示例 2: 使用一个 auto_ptr
    //
    void g()
    {
      T* pt1 = new T;
      // 现在,我们有了一个分配好的对象

      // 将所有权传给了一个auto_ptr对象
      auto_ptr<T> pt2( pt1 );

      // 使用auto_ptr就像我们以前使用简单指针一样
      *pt2 = 12;       // 就像 "*pt1 = 12;"
      pt2->SomeFunc(); // 就像 "pt1->SomeFunc();"

      // 用get()来获得指针的值
      assert( pt1 == pt2.get() );

      // 用release()来撤销所有权
      T* pt3 = pt2.release();

      // 自己删除这个对象,因为现在
      // 没有任何auto_ptr拥有这个对象
      delete pt3;

    } // pt2不再拥有任何指针,所以不要
      // 试图删除它...ok,不要重复删除

最后,我们可以使用auto_ptr的reset()函数来重置auto_ptr使之拥有另一个对象。如果这个auto_ptr已经拥有了一个对象,那么,它会先删除已经拥有的对象,因此调用reset()就如同销毁这个auto_ptr,然后新建一个并拥有一个新对象:

    // 示例 3: 使用reset()
    //
    void h()
    {
      auto_ptr<T> pt( new T(1) );

      pt.reset( new T(2) );
        // 删除由"new T(1)"分配出来的第一个T

    } // 最后,pt出了作用域,
      // 第二个T也被删除了

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/433424.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

unity镜头边缘羽化_【后期修图】如何利用Ps中的自适应广角滤波器校正镜头失真?...

当用广角镜头拍摄对象时&#xff0c;透视问题通常以线条的形式出现&#xff0c;这应该是直的&#xff0c;但看起来是弯曲的和扭曲的。这通常被称为桶形失真&#xff0c;其主要发生在广角镜头中&#xff0c;因为图像的放大率越远&#xff0c;主体离镜头的光轴越远。简单来说&…

mysql查看事件任务内容_MySql事件计划任务

DROP EVENT IF EXISTS eve1;DELIMITER $$CREATE EVENT eve1 ON SCHEDULE EVERY 1 SECOND STARTS NOW() ENDS NOW()1ON COMPLETION PRESERVEDISABLEDOBEGINUPDATE testtable1 SET age age1 WHERE id 1;END$$DELIMITER ;SELECT * FROM testtable1;SELECT NOW();/*标准创建语句E…

Delphi 对象的创建(create)与释放(free/destory)

Delphi 对象的创建(create)与释放(free/destory) 1、Create参数为:nil/self/application的区别&#xff0c;最好能看到实际效果的区别 例如: My : TMy.Create(X); 其中的 X 将会成为控件 My 的 Owner 属性, 可能会不只一个控件把 X 当作 Owner. 当 X 释放时, 它会同时释放那些…

用引用返回值(转)

函数返回值时&#xff0c;要生成一个值的副本。而用引用返回值时&#xff0c;不生成值的副本。例如&#xff0c;下面的程序是有关引用返回的4种形式&#xff1a;//*********************//**   ch9_6.cpp  **//********************* #include <iostream.h> float tem…

python 串口助手 简书_python用pyserial读取串口问题解决

object is not callableError:‘bool’ object is not callable没有返回值正确代码&#xff1a;ser serial.Serial(COM7, 115200, 8, N, 1)flag ser.is_open原因&#xff1a;调用属性is_open时将其视为函数&#xff0c;写成 ser.is_open()。关于is_open的功能及用法&#xff…

mysql用binlog恢复数据_利用mysql的binlog恢复数据

MySQL Binary Log也就是常说的bin-log, ,是mysql执行改动产生的二进制日志文件,其主要作用有两个:* 数据回复* 主从数据库。用于slave端执行增删改&#xff0c;保持与master同步。1.开启binary log功能需要修改mysql的配置文件&#xff0c;本篇的实验环境是win7&#xff0c;配置…

Perl,Python,Ruby,Javascript 四种脚本语言比较

Perl 为了选择一个合适的脚本语言学习&#xff0c;今天查了不少有关Perl&#xff0c;Python&#xff0c;Ruby&#xff0c;Javascript的东西&#xff0c;可是发现各大阵营的人都在吹捧自己喜欢的语言&#xff0c;不过最没有争议的应该是Javascript现阶段还不适合用来做独立开发&…

C++中的IPv6网络程序设计

IPv4 最初是由美国国防部开发的用于网际互联&#xff08;IP&#xff09;协议&#xff0c;后来它不仅发展了TCP&#xff0c;而且还进一步发展了IPv4&#xff08;IP 协议4.0版&#xff09;。IPv4现在已经广泛应用于Internet网络中&#xff0c;同时也应用于大多数计算机系统&#…

python regex_Python 正则表达式

定义在编写处理字符串的程序或网页时&#xff0c;经常会有查找符合某些复杂规则的字符串的需要。正则表达式就是用于描述这些规则的工具。简而言之&#xff1a;正则表达式就是记录文本规则的代码。特点:操作字符串1.更快的方式操作字符串&#xff1b;(表单校验&#xff0c;数据…

python 怎么处理json_Python是怎样处理json模块的

首先&#xff0c;了解下什么是JSON&#xff1f;JSON&#xff1a;JavaScript Object Notation 【JavaScript 对象表示法】JSON 是一种轻量级的数据交换格式&#xff0c;完全独立于任何程序语言的文本格式。一般&#xff0c;后台应用程序将响应数据封装成JSON格式返回。JSON的基本…

UEditor1.2.6.0在.net环境下使用

UEditor1.2.6.0 1.百度百科词条 2.UEditor官方网站 【CKEditorCKFinder的配置实用&#xff0c;可查看博主另一篇文章】 第一次接触UEditor还是在2011年的下半年里&#xff0c;当时由于需要找一款富文本编辑器进行新闻的网站开发&#xff0c;当时UEditor异常较多&#xff0c;就将…

sql 删除数据_从零开始学SQL:是什么、如何安装、基本语法、表格(创建、删除、更新)、数据(插入、删除、更新)...

一、学习知识的黄金圈思维用黄金圈思维分析自己学习SQL&#xff0c;能增加自己的效率和坚持下去的动力。二、SQL基础知识1.数据库概念&#xff1a; database &#xff0c;按照数据结构来组织、存储和管理数据的仓库。2.关系数据库&#xff1a;多张表表之间的关系表&#xff1a;…

ubuntu ip设置

在Debian(ubuntu就是Debian类linux)中网卡的设置可以通过/etc/network/interfaces文件来进行&#xff0c;具体可分为三种不同的配置方式&#xff1a;DHCP自动获取、静态分配IP地址和PPPoE宽带拨号。 具体设置如下&#xff1a; 在进行配置之前&#xff0c;首先进入/etc/networ…

在mysql中你可以为视图创建索引_mysql中创建视图、索引

数据库的三级模式两级映射: 存储文件------>基本表----->视图 内模式 ------->模式 ------>外模式 一、视图 1、什么是视图: 视图是从一个或多个表中导出来的表,是一种虚拟存在的表。 视图就像一个窗口,通过这个窗口可以看到系统专门提供的数据。 这样,用…

mysql 转换编码

ALTER TABLE tablename CONVERT TO CHARACTER SET UTF8;转载于:https://www.cnblogs.com/wuruile/p/3164920.html

嵌入式Linux操作系统的版本查询

嵌入式Linux版本查询&#xff1a; uname -a 显示内核版本 uname -m 显示ARM处理器内核信息 uname -v 显示操作系统的编译时间 linux版本&#xff1a;在linux/utsrelease.h中定义&#xff1a; [cpp] view plaincopy#define UTS_RELEASE "2.6.31-liuqimingxinguodu.com--…

函数使用了堆栈的字节超过_在C语言中如何访问堆栈?

堆栈一般是用来保存变量之类的东西&#xff08;静态变量在内存中&#xff0c;虽然堆栈就是内存的一部分&#xff0c;但为了防止歧义&#xff0c;还是分成两部分来说&#xff09;&#xff0c;一般情况下没必要去故意读取堆栈的值&#xff0c;变量用变量名就可以直接访问&#xf…

怎么解决相位抵消_【录音教程】如何防止话筒拾音的声学相位抵消

设想一下你以单声道的模式为一个吉他歌手做扩声&#xff0c;一支人 声听起来比较古怪&#xff0c;有点“空”&#xff0c;同时有滤波器之类的效果声。为什么会这样&#xff1f;主唱话筒拾取歌手的演唱&#xff0c;同时拾取箱琴的话筒也串入了歌手的声音(见图1)。吉 他话筒离主唱…

win32 ipv6 bind 10014问题

这两天实验了一下&#xff0c;windows xp系统下的 ipv6 udp网络通信。要在windows xp下测试ipv6&#xff0c;首先在命令行窗口下 执行 ipv6 install 和 net start tcpipv6 命令。 在bind本地地址时&#xff0c;发现没法使用 in6addr_any 这通配地址。即下面这种使用方式&a…

string 找出所有数字 index_发现规律,解决整数转罗马数字

嗨&#xff0c;各位&#xff01;我们又准时见面了&#xff0c;即将迎来难得的周末时光&#xff0c;我们今天来一道相对简单的题目逻辑梳理的题目&#xff0c;原定的动态规划的常见题型我们放在周末进行更新。话不多说&#xff0c;我们先看题目&#xff1a; 01 . 题目罗马数字包…