《白话C++》第10章 STL和boost,Page67~70 std::auto_ptr

std::auto_ptr可以不经意间转移裸指针控制权

std::auto_ptr持有裸指针的控制权,却可以随随便便看似不经意地转移给另一个auto_ptr:

#include <iostream>
#include <memory>using namespace std;struct S
{int a;void SetA(int a){this->a = a;}~S(){cout << "~S: bye-bye" << endl;}
};void test_auto_ptr_crash()
{auto_ptr <S> aps(new S);auto_ptr <S> aps2(aps); //转移对裸指针的所有权aps2->SetA(99);aps->SetA(100); //有可能造成程序挂掉
}

023行,aps获得并负责管理一个新的裸指针(通过new S所得);

024行,看是普通的“拷贝构造”操作,实际确实在做转移操作,aps拱手让出的原是它拥有且负责管理的裸指针

025行,aps2拥有,并可以控制该裸指针了

026行,“旧人”aps还想操作裸指针,但此时它拥有的裸指针是“nullptr”。

auto_ptr作为入参,传给函数:

再看看复杂点的情况,比如将auto_ptr作为入参,传给函数:

void foo(auto_ptr<S> aps)
{;
}void call_foo()
{auto_ptr <S> aps(p);/**< 当实参传递时,需要复制,这一复制,原auto_ptr即失去了原有的裸指针 */foo(aps);cout << "===============" << endl;aps->SetA(100);//程序通常要挂掉……
}

演示auto_ptr作为入参:

foo函数的入参是一个auto_ptr,而不是“auto_ptr <S>&”或“auto_ptr<S>*”,因此当实参传递时,需要复制,这一复制,原auto_ptr即失去了原有的裸指针,那就试试将入参改成auto_ptr的引用:

入参改为auto_ptr的引用:

void foo2(auto_ptr<S> & aps)
{;
}

这将传递,没有发生裸指针转移所有权的事,但进入函数之后,万一又有复制的需要:

void foo2(auto_ptr<S> & aps)
{//如果有复制,还是会被转移走的。auto_ptr<S> aps2(aps);
}

以引用方式传递auto_ptr给某个函数,调用者更加没有安全感了,因为调用处原auto_ptr到底会不会被“转移”走,调用者完全不可控。

常量引用:

如果一个函数明确不准备转移auto_ptr入参的所有权,解决方法是“常量引用”:

/**< 明确不准备转移auto_ptr入参的所有权,解决方法是“常量引用” */
void foo3(auto_ptr <S> const& aps)
{auto_ptr <S> aps2(aps); //编译不过去aps.release(); //也编译不过去//delete aps.get();//代码阻止不了某些程序员的猥琐
}

foo3函数作者感到迷惑了:我只是想以“aps”为模子复制一份,为什么编译不能过呢?

auto_ptr本身也感到委屈:“我早就说过了,我的‘复制’就是转移,是你们记不住呀”

auto_ptr类模板的拷贝构造函数:

典型的拷贝构造auto_ptr的拷贝构造

class XXX

{

public:

        ...

        XXX(XXX const& other);

        ...

};

template <typename T>

class auto_ptr

{

public:

        ...

        auto_ptr(auto_ptr& other)

        ...

};

对比两边的构造函数声明,左边入参带有const修饰,右边的没有。auto_ptr没有欺骗我们,它特意声明拷贝构造时的入参不能是常量,原因就在于它复制other时,还会修改other的内容,这是合法的,因为C++没规定拷贝构造的入参一定是const。只是这违反了直觉,违反了“拷贝构造”的语义。所以C++标准委员会决定抛弃auto_ptr。

auto_ptr作为函数返回值:

auto_ptr作为函数返回值的做法,在旧代码中很常见。

std::auto_ptr <S> CreateS()
{...S* ps = new S;...return std::auto_ptr <S> (ps);
}

这个做法挺灵活的:如果调用者就不想理会什么智能指针,那完全还可以使用裸指针接盘:

//得到智能指针管理的指针,原智能指针不再占有内存
S* sp = CreateS().release();
//按照常规方式使用,包括负责释放
delete sp; 

如果调用者认同智能指针有一定的方便些,那就保留auto_ptr接下:

//保留auto_ptr,以方便自动释放
std::auto_ptr <S> asp = CreateS(); 

如果调用了CreateS()函数却不理会其返回值:

CreateS();//不理会返回值,反正它会被自动释放……

如果代码这么写:

S* sp = CreateS().get(); //可怕

这样写,本意上应该是想达到第一种写法的效果,但后果相当可怕。为什么?

因为用get()函数得到的裸指针后,智能指针依旧管理着裸指针,如果裸指针使用delete删除后,会导致智能指针失效。

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

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

相关文章

SQL Extractor 数据库修复取证大师-数据库修复专家

SQL Extractor 数据库修复取证大师介绍 SQL Extractor 数据库修复取证大师 功能介绍&#xff1a;SQL Extractor数据库修复取证大师最新版本10.94软件特色:针对勒索病毒加密的SQL 数据库有特殊的修复算法,可匹配用友,金蝶数据库结构关系. 支持7.0、SQL2000、SQL2005、SQL2008、…

可视化低代码表单设计器

JNPF 表单设计器是一款在线可视化表单建模工具&#xff0c;基于VueSpringboot技术开发&#xff0c;具有组件丰富、操作简单、所见即所得等特性&#xff0c;既能够设计普通的数据录入表单&#xff0c;也能够配合流程设计出各类审批流转表单。 应用地址&#xff1a;https://www.j…

ForkJoin 的使用以及原理

原理 Fork-Join 是一种并行计算模式&#xff0c;它通常用于解决递归式或者分治式的问题。其原理基于将一个大的任务划分成若干个小任务&#xff0c;然后并行地执行这些小任务&#xff0c;最后将它们的结果合并起来得到最终的结果。 具体来说&#xff0c;Fork-Join 模式包含两个…

报错405(errAxiosError: Request failed with status code 405)

errAxiosError: Request failed with status code 405 前端调用接口的方法跟后台定义接口的方法不一致

论文阅读:MotionNet基于鸟瞰图的自动驾驶联合感知和运动预测

MotionNet: Joint Perception and Motion Prediction for Autonomous Driving Based on Bird’s Eye View Maps MotionNet&#xff1a;基于鸟瞰图的自动驾驶联合感知和运动预测 论文地址&#xff1a;MotionNet: Joint Perception and Motion Prediction for Autonomous Drivi…

C++-opencv的imread、imshow、waitkey、namedWindow

在C中使用OpenCV时&#xff0c;imread和imshow是两个非常基础且常用的函数&#xff0c;用于读取图像和显示图像。以下是这两个函数的简要说明和如何一起使用它们的示例。 imread函数 imread用于从指定的文件路径读取图像。它将图像读入为cv::Mat对象&#xff0c;这是OpenCV中…

走进水墨世界,寻找传统之美

为深入了解中国传统水墨文化的底蕴及其在当代的价值&#xff0c;2024年2月16日&#xff0c;曲阜师范大学计算机学院“古韵新声&#xff0c;格物致‘知’”实践队的队员王涵智走进山东省高唐县巩德春艺术馆展开社会实践。实践队员以探访艺术馆为契机&#xff0c;领略传统水墨文化…

Academic Inquiry|投稿状态分享(ACS,Wiley,RSC,Elsevier,MDPI,Springer Nature出版社)

作为科研人员&#xff0c;我们经常会面临着向学术期刊投稿的问题。一般来说&#xff0c;期刊的投稿状态会在官方网站上进行公示&#xff0c;我们可以通过期刊的官方网站或者投稿系统查询到我们投稿的论文的状态&#xff0c;对于不同的期刊在投稿系统中会有不同的显示。 说明&am…

如何查看HP打印机的Wi-Fi密码?这里提供三种方法

如果你计划通过Wi-Fi Direct从笔记本电脑或智能手机无线打印&#xff0c;则需要HP打印机密码。有了这个功能&#xff0c;打印机可以创建自己的Wi-Fi网络&#xff0c;你不需要依赖其他Wi-Fi网络。你只需转到设备的Wi-Fi设置&#xff0c;将其连接到Wi-Fi Direct&#xff0c;然后立…

OpenAI全新发布的Sora,到底意味着什么?

16日凌晨&#xff0c;OpenAI发布了文本视频的工具&#xff08;text-do-video&#xff09;Sora&#xff0c;整个世界再次被震撼。 Sora的出现&#xff0c;到底意味着什么&#xff1f; 目录 Sora的背景与概述Sora是什么&#xff1f;能为我们做些什么&#xff1f;存在的一些问题 文…

字节8年经验之谈 —— 详解python自动化单元测试!

1. 前言 说实话&#xff0c;除了测试要求&#xff0c;我实在不知道写单元测试有什么意义&#xff0c;一个函数50行代码&#xff0c;有多种参数组合&#xff0c;为了测试这些条件&#xff0c;需要编写测试用例&#xff0c;写完的测试用例比需要测试的函数还长。也就是说&#x…

14-树-二叉树的最小深度

这是树的第14篇算法&#xff0c;力扣链接。 给定一个二叉树&#xff0c;找出其最小深度。 最小深度是从根节点到最近叶子节点的最短路径上的节点数量。 说明&#xff1a;叶子节点是指没有子节点的节点。 示例 1&#xff1a; 输入&#xff1a;root [3,9,20,null,null,15,7] 输出…

ubuntu18.04运行DynaSLAM,实例分割+多视图几何+背景修复

博主电脑上之前就安装了ORB-SLAM2所需的环境&#xff0c;所以baseline为ORB-SLAM2的算法几乎都是直接./build.sh即可。需要我们安装的内容就是python的环境&#xff0c;Pytorch或者TensorFlow&#xff0c;以及下载预训练模型和数据集。 一、安装ORB-SLAM2所需的库 C11 or C0x…

全网Bento和3D?点评2024年UX/UI设计趋势

2024年已经到来&#xff0c;对于UX/UI设计领域来说&#xff0c;这可能是过去若干年来UI / UX趋势最统一、最确定的一年。在接下来的文章中&#xff0c;笔者将在点评各个设计趋势的同时&#xff0c;分析现象背后的原因&#xff0c;并给新入行的设计师一些成长的建议。 什么是UI和…

数据结构-邻接矩阵

介绍 邻接矩阵&#xff0c;是表示图的一种常见方式&#xff0c;具体表现为一个记录了各顶点连接情况的呈正方形的矩阵。 假设一共有以下顶点&#xff0c;其连接关系如图所示 那么&#xff0c;怎么表示它们之间的连接关系呢&#xff1f; 我们发现&#xff0c;各条边所连接的都…

C语言题目:一些简单的编程和递归题目

以下的题目的较难的点都在注释里面讲解清楚了 一. 1.喝汽水&#xff0c;1瓶汽水1元&#xff0c;2个空瓶可以换一瓶汽水&#xff0c;给20元&#xff0c;可以喝多少汽水&#xff08;编程实现&#xff09;。 代码实现&#xff1a; int main() {int money 20;int price 1;int e…

C#,二进制数的非0位数统计(Bits Count)的算法与源代码

计算一个十进制数的二进制表示有多少位1&#xff1f; 1 遍历法&#xff08;递归或非递归&#xff09; 使用循环按位统计1的个数。 2 哈希查表法 利用一个数组或哈希生成一张表&#xff0c;存储不同二进制编码对应的值为1的二进制位数&#xff0c;那么在使用时&#xff0c;只…

(每日持续更新)信息系统项目管理(第四版)(高级项目管理)考试重点整理第10章 项目进度管理(五)

博主2023年11月通过了信息系统项目管理的考试&#xff0c;考试过程中发现考试的内容全部是教材中的内容&#xff0c;非常符合我学习的思路&#xff0c;因此博主想通过该平台把自己学习过程中的经验和教材博主认为重要的知识点分享给大家&#xff0c;希望更多的人能够通过考试&a…

控制程序执行流程

资源 资源下载 【免费】突破密码认证程序&#xff08;修改函数返回地址&#xff09;资源-CSDN文库 资源内容 源码 在上一篇文章里 修改函数返回地址-CSDN博客 流程 对程序进行编译 思路 了解栈的情况&#xff08;函数地址、缓冲区偏移量&#xff09;程序中密码认证的地…

SHERlocked93 的 2023 年终总结

工作之后感觉一年一年过的太快&#xff0c;没有个记录连回忆都无从回忆起&#xff0c;之前的年终总结&#xff1a; SHERlocked93 的 2022 年终总结SHERlocked93 的 2021 年终总结SHERlocked93 的 2020 年终总结SHERlocked93 的 2019 年终总结SHERlocked93 的 2018 年终总结SHER…