《白话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、…

ES实战--性能提升

触发冲刷的条件: 1.内存缓冲区已满 2.自上次冲刷后超过了一定时间 3.事务日志达到了一定阀值 对名为get-together的Elasticsearch索引执行优化操作&#xff0c;将索引中的数据段&#xff08;segments&#xff09;合并到指定的数量1 GET /get-together/_optimize?max_num_segm…

【微信小程序】小程序的双线程架构,为什么要设计成双线程的

微信小程序是双线程的&#xff0c;有渲染层和逻辑层两个执行环境&#xff0c;渲染层负责页面的渲染和样式&#xff0c;逻辑层负责小程序的逻辑和数据处理。 渲染线程&#xff1a;负责渲染界面&#xff0c;包括解析 wxml&#xff0c;wxss&#xff0c;样式计算&#xff0c;布局排…

可视化低代码表单设计器

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

Python函数——函数介绍

一、引言 在Python编程中&#xff0c;函数是构建高效代码的关键。通过创建可重用的代码块&#xff0c;我们可以使程序更加清晰、易读且易于维护。在本文中&#xff0c;我们将深入了解Python函数的基本概念及其特性。 二、Python函数的基本概念 函数是一段具有特定功能的代码块…

ForkJoin 的使用以及原理

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

atomic_fetch_and(i, v)

atomic_fetch_and是一个原子操作函数&#xff0c;用于在多线程环境中执行位与操作&#xff08;AND操作&#xff09;。它能够保证在并发情况下对共享变量进行安全地操作&#xff0c;避免出现数据竞争和不一致性问题。具体来说&#xff0c;atomic_fetch_and函数会将一个指定值 i …

报错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;然后立…

Python爬虫JSON网址selenium实战笔记

仅供学习参考 一、获取特定文本和json链接 from selenium import webdriver from selenium.webdriver.common.by import By from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC# 指定 Chrome 驱动程…

Java vs JavaScript: 了解关键区别

1. 语法和结构: Java: Java 是一种静态类型语言&#xff0c;这意味着在定义变量时需要声明每个变量的数据类型。在 Java 中&#xff0c;一个简单的 “Hello, World!” 程序如下所示&#xff1a; public class HelloWorld {public static void main(String[] args) {System.out…

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…

可观测集合 ObservableCollection<T>、BindingList<T>

引言 WPF中经常使用的是集合类型,数据条目经常按集合类型进行保存收纳,当我们向用户公开一些命令:添加、删除或刷新整个列表,如何通知界面进行准确的刷新呢?这时我们就需要使用可被观测的集合 ObservableCollection<T>、BindingList 1、ObservableCollection<T…

257.【华为OD机试真题】幼儿园篮球游戏(贪心算法-JavaPythonC++JS实现)

🚀点击这里可直接跳转到本专栏,可查阅顶置最新的华为OD机试宝典~ 本专栏所有题目均包含优质解题思路,高质量解题代码(Java&Python&C++&JS分别实现),详细代码讲解,助你深入学习,深度掌握! 文章目录 一. 题目二.解题思路三.题解代码Python题解代码JAVA题解…

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

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