条款25:考虑写出一个不抛出异常的swap函数
1.前言
swap是个有趣的函数,原本它只是STL的一部分,而后成为异常安全编程的基石,以及用来处理自我赋值可能性的一个常见机制。由于swap功能如此强大,适当的实现很重要。然而在非凡的重要性之外它也带来了非凡的复杂度。
所谓swap两对象值,意思是将两对象的值彼此赋予对方。缺省情况下swap动作可由标准程序库提供的swap算法完成。其典型的实现方式如下:
namespace std{template<typename T>void swap(T& A,T& b){T temp(a);a=b;b=temp;}
}
只要类型T支持copying(通过copy构造函数和copy assignment操作符完成),缺省的swap实现代码就会帮你置换类型为T的对象,不需要为此做另外的工作。
该缺省的swap实现版本十分平淡,无法刺激你的肾上腺。它涉及到三个对象的复制:a复制到temp,b复制到a,以及temp复制到b。但是对于某些类型而言,这些复制动作没有必要:对那种情况而言swap缺省行为等于杀机用牛刀。
2.实例
最主要的一种类型就是“以指针指向一个对象,内含真正数据”那种类型。这种设计的常见表现形式就是所谓的“pimpl手法”。如果以这种手法设计Widget class,看起来像这样:
class WidgetImpl{ //针对Widget数据而设计的classpublic:
...
private:
int a,b,c;//可能有许多数据
std::vector<double> v;//意味复制时间很长
。。。};
class Widget{public:Widget(const Widget& rhs);Widget& operator=(const Widget& rhs){...*pImpl=*(rhs.pImpl);}...private:Widget Impl* pImpl;//指针,所有对象内含Widget
}
一旦要置换两个Widget对象值,我们唯一需要做的就是置换其pImpl指针,但缺省的swap算法不知道这一点,它不止复制三个widgets,还复制三个WidgetImpl对象。非常缺乏效率。
我们希望能够告诉std::swap,当widget被置换时,真正该做的是置换其内部的pImpl指针。确切实践这个思路的一个做法是:将std::swap针对Widget特化,下面是基本的构想,但目前这个形式无法通过编译:
namespace std{template<>void swap<Widget>(Widget& a,Widget& b){swap(a.pImpl,b.pImpl);}
}
这个函数一开始得"template<>"表示它是std::swap的一个全特化版本,函数名称之后的"<Widget>"表示这一特化版本系针对“T是Widget”而设计。换句话说当一般性的swap template施行于Widget身上便会启用这个版本。通常我们不能够改变std命名空间内的任何东西,但可以为标准template制造特化版本,使它专属于我们自己的classes。
但是该函数无法通过编译,因为它企图访问a和b内的pImpl指针,而那却是private,我们可以将这个特化版本声明为friend,但和以往的规矩不太一样:我们令Widget声明为swap的public成员函数做真正的置换工作,然后将std::swap特化,令它调用该成员函数:
class Widget{public:...void swap(Widget& other){using std::swap;swap(pImpl,other.pImpl);//若要置换Widgets就置换其pImpl指针}...
};
namespace std{template<>void swap<Widget>(Widget& a,Widget& b){a.swap(b);//若要置换Widgets,调用其swap成员函数}
}
这种做法不只能够通过编译,还与STL容器有一致性,因为所有STL容器也都提供有public swap成员函数和std::swap特化版本。
然而假设Widget和WidgetImpl都是class templates而非classes,也许我们可以将Widget内的数据类型加以参数化:
template<typename T>
class WidgetImpl{...};
template<typename T>
class Widget{....};
相关文章:
条款25:考虑写出一个不抛出异常的swap函数
1.前言 swap是个有趣的函数,原本它只是STL的一部分,而后成为异常安全编程的基石,以及用来处理自我赋值可能性的一个常见机制。由于swap功能如此强大,适当的实现很重要。然而在非凡的重要性之外它也带来了非凡的复杂度。 所谓swa…...
linux 中crontab 定时任务计划创建时间文件夹示例
1.创建一个sh脚本 /usr/bin/mkdir 是mkdir命令的路径 /usr/bin/chmod 是chmod命令的路径 2.编辑定时任务 crontab -e...
欣赏动态之美,不如欣赏C语言实现动态内存管理之美 ! ! !
本篇会加入个人的所谓‘鱼式疯言’ ❤️❤️❤️鱼式疯言:❤️❤️❤️此疯言非彼疯言 而是理解过并总结出来通俗易懂的大白话, 我会尽可能的在每个概念后插入鱼式疯言,帮助大家理解的. 可能说的不是那么严谨.但小编初心是能让更多人能接受我们这个概念 !࿰…...
from pycocotools.coco import COCO报错
需要注意的是,自己的系统是windows还是linux的系统: windows系统的安装: pip install pycocotools-windows linux的系统安装: pip install pycocotools 别用错了命令哦!...
CentOS服务自启权威指南:手动启动变为开机自启动(以Jenkins服务为例)
前言 CentOS系统提供了多种配置服务开机自启动的方式。本文将介绍其中两种常见的方式, 一种是使用Systemd服务管理器配置,不过,在实际中,如果你已经通过包管理工具安装的,那么服务通常已经被配置为Systemd服务&#…...
第二百零一回 介绍一个三方包open_settings
文章目录 1. 概念介绍2 使用方法3 代码与效果3.1 示例代码3.2 运行效果 4. 经验分享 我们在上一章回中介绍了Form Widget相关的内容,本章回中将介绍Form系列组件的验证与提交功能.闲话休提,让我们一起Talk Flutter吧。 1. 概念介绍 我们在这里说的的验…...
iview Table实现跨页勾选记忆功能以及利用ES6的Map数据结构实现根据id进行对象数组的去重
因为iview Table组件的勾选是选中当前页的所有数据,当我们切到别的页面时,会发送请求给后端,这个时候就会刷新我们之前页码已经选中的数据。现在有个需求就是,在我们选择不同页码的数据勾选中之后,实现跨页勾选记忆功能,就是说已经打钩了的数据,不管切到哪一页它都是打钩…...
【Spring 源码】 贯穿 Bean 生命周期的核心类之 AbstractAutowireCapableBeanFactory
🚀 作者主页: 有来技术 🔥 开源项目: youlai-mall 🍃 vue3-element-admin 🍃 youlai-boot 🌺 仓库主页: Gitee 💫 Github 💫 GitCode 💖 欢迎点赞…...
漏洞复现-某友UFIDA NC系统某接口未授权访问漏洞(附漏洞检测脚本)
免责声明 文章中涉及的漏洞均已修复,敏感信息均已做打码处理,文章仅做经验分享用途,切勿当真,未授权的攻击属于非法行为!文章中敏感信息均已做多层打马处理。传播、利用本文章所提供的信息而造成的任何直接或者间接的…...
树莓派5安装opencv
1 建立虚拟环境 参考网站 https://www.piwheels.org/faq.html#venv 虚拟环境建立过程: To create a virtual environment: $ sudo apt install virtualenv python3-virtualenv -y $ virtualenv -p /usr/bin/python3 testpip sudo apt install virtualenv pytho…...
【测试开发】Python+Django实现接口测试工具
PythonDjango接口自动化 引言: 最近被几个公司实习生整自闭了,没有基础,想学自动化又不知道怎么去学,没有方向没有头绪,说白了其实就是学习过程中没有成就感,所以学不下去。出于各种花里胡哨的原因…...
从 MQTT、InfluxDB 将数据无缝接入 TDengine,接入功能与 Logstash 类似
利用 TDengine Enterprise 和 TDengine Cloud 的数据接入功能,我们现在能够将 MQTT、InfluxDB 中的数据通过规则无缝转换至 TDengine 中,在降低成本的同时,也为用户的数据转换工作提供了极大的便捷性。由于该功能在实现及使用上与 Logstash 类…...
友元c++
#include <iostream> #include <string> using namespace std; class Lovers//爱人关系,基类 { public: Lovers(string theName);// void kiss(Lovers *lover); void ask(Lovers *lover, string something); protected: string name; friend cla…...
java: 错误: 不支持发行版本 6
文章目录 背景一、问题二、问题排查三、最终解决方案 背景 我本地安装的jdk版本是jdk 17,在项目父工程中配置的版本是8版本,每次我启动项目时都会报错。 一、问题 二、问题排查 首先我排查了父工程pom.xml中的配置,配置的是8版本࿰…...
qml刷新C++中的QImage图像
第一步:重写QQuickImageProvider类 #include <QQuickImageProvider>class CQuickImagePainter : public QQuickImageProvider { public:CQuickImagePainter();QImage requestImage(const QString&id, QSize *, const QSize &);QPixmap requestPixm…...
IJCAI 2024 International Joint Conference on Artificial Intelligence
目录 1、 重要1.1 官网:1.2 提交网址:1.3 模板 (latex & word) 2、 Call for Papers2.1 Important Dates2.2 Details 3、 注意事项4 New in 20245 Simplified procedure for resubmission information6、 Submission Process …...
使用Python Flask搭建Web问答应用程序并发布到公网远程访问
使用Python Flask搭建web问答应用程序框架,并发布到公网上访问 文章目录 使用Python Flask搭建web问答应用程序框架,并发布到公网上访问前言1. 安装部署Flask并制作SayHello问答界面2. 安装Cpolar内网穿透3. 配置Flask的问答界面公网访问地址4. 公网远程…...
android 13.0 app应用安装白名单
1.概述 在13.0系统rom定制化开发中,客户需求要实现应用安装白名单功能,在白名单之中的应用可以安装,其他的app不准安装,实现一个 控制app安装的功能,这需要从app安装流程入手就可以实现功能 PMS就是负责管理app安装的,功能就添加在这里就可以了,接下来看具体实现这个功能…...
SSL证书HTTPS保护服务
SSL证书属于数字证书的其中一种,广泛用于https协议,从而可以让数据传输在加密前提下完成,确保HTTPS网络安全是申请SSL证书必要工作。 SSL证书是主要用于https是一种加密协议,仔细观察网站地址会发现目前主流的网址前面都会有http…...
快速认识什么是:Docker
Docker,一种可以将软件打包到容器中并在任何环境中可靠运行的工具。但什么是容器以及为什么需要容器呢?今天就来一起学快速入门一下Docker吧!希望本文对您有所帮助。 假设您使用 Cobol 构建了一个在某种奇怪风格的 Linux 上运行的应用程序。您…...
【Python】 -- 趣味代码 - 小恐龙游戏
文章目录 文章目录 00 小恐龙游戏程序设计框架代码结构和功能游戏流程总结01 小恐龙游戏程序设计02 百度网盘地址00 小恐龙游戏程序设计框架 这段代码是一个基于 Pygame 的简易跑酷游戏的完整实现,玩家控制一个角色(龙)躲避障碍物(仙人掌和乌鸦)。以下是代码的详细介绍:…...
利用ngx_stream_return_module构建简易 TCP/UDP 响应网关
一、模块概述 ngx_stream_return_module 提供了一个极简的指令: return <value>;在收到客户端连接后,立即将 <value> 写回并关闭连接。<value> 支持内嵌文本和内置变量(如 $time_iso8601、$remote_addr 等)&a…...
大话软工笔记—需求分析概述
需求分析,就是要对需求调研收集到的资料信息逐个地进行拆分、研究,从大量的不确定“需求”中确定出哪些需求最终要转换为确定的“功能需求”。 需求分析的作用非常重要,后续设计的依据主要来自于需求分析的成果,包括: 项目的目的…...
基于距离变化能量开销动态调整的WSN低功耗拓扑控制开销算法matlab仿真
目录 1.程序功能描述 2.测试软件版本以及运行结果展示 3.核心程序 4.算法仿真参数 5.算法理论概述 6.参考文献 7.完整程序 1.程序功能描述 通过动态调整节点通信的能量开销,平衡网络负载,延长WSN生命周期。具体通过建立基于距离的能量消耗模型&am…...
高频面试之3Zookeeper
高频面试之3Zookeeper 文章目录 高频面试之3Zookeeper3.1 常用命令3.2 选举机制3.3 Zookeeper符合法则中哪两个?3.4 Zookeeper脑裂3.5 Zookeeper用来干嘛了 3.1 常用命令 ls、get、create、delete、deleteall3.2 选举机制 半数机制(过半机制࿰…...
《通信之道——从微积分到 5G》读书总结
第1章 绪 论 1.1 这是一本什么样的书 通信技术,说到底就是数学。 那些最基础、最本质的部分。 1.2 什么是通信 通信 发送方 接收方 承载信息的信号 解调出其中承载的信息 信息在发送方那里被加工成信号(调制) 把信息从信号中抽取出来&am…...
【论文笔记】若干矿井粉尘检测算法概述
总的来说,传统机器学习、传统机器学习与深度学习的结合、LSTM等算法所需要的数据集来源于矿井传感器测量的粉尘浓度,通过建立回归模型来预测未来矿井的粉尘浓度。传统机器学习算法性能易受数据中极端值的影响。YOLO等计算机视觉算法所需要的数据集来源于…...
令牌桶 滑动窗口->限流 分布式信号量->限并发的原理 lua脚本分析介绍
文章目录 前言限流限制并发的实际理解限流令牌桶代码实现结果分析令牌桶lua的模拟实现原理总结: 滑动窗口代码实现结果分析lua脚本原理解析 限并发分布式信号量代码实现结果分析lua脚本实现原理 双注解去实现限流 并发结果分析: 实际业务去理解体会统一注…...
《C++ 模板》
目录 函数模板 类模板 非类型模板参数 模板特化 函数模板特化 类模板的特化 模板,就像一个模具,里面可以将不同类型的材料做成一个形状,其分为函数模板和类模板。 函数模板 函数模板可以简化函数重载的代码。格式:templa…...
JVM 内存结构 详解
内存结构 运行时数据区: Java虚拟机在运行Java程序过程中管理的内存区域。 程序计数器: 线程私有,程序控制流的指示器,分支、循环、跳转、异常处理、线程恢复等基础功能都依赖这个计数器完成。 每个线程都有一个程序计数…...
