条款7:千万不要重载,||和,操作符

&&和||

和C一样,C++对于“真假值表达式”采用所谓的“骤死式”评估方式。意思是一旦该表达式的真假值确定,即使表达式中还有部分尚未检验,整个评估工作仍告结束。

举个例子,在下面情况中:

char *p;
...
if ((p!=0)&&(strlen(p)>10))

你无须担心调用strlen时p是否为null指针,因为如果“p是否为0”的测试结果是否定的,strlen 就绝不会被调用。

同样道理,以下代码:

int rangeCheck(int index)
{
if ((index < lowerBound) || (index >upperBound))
//...
}

如果 index小于 lowerBound,它就绝不会被拿来和 upperBound比较。

这是C/C++社区中人尽皆知的一个行为,其年代已经古老得不复记忆。这是他们预期而毫不犹豫的行为。甚至他们所写的程序必须依赖这种“骤死式”评估方式才能表现出正确行为。例如,上一段代码所依持的一个重要事实是,如果是个null 指针,strlen 就不会被调用,因为对C++standard(以及Cstandard)来说,对一个 null 指针调用strlen,结果不可预期。

C++允许你为“用户定制类型”量身定做&&和||操作符。做法是对operator&& 和 operatorl| 两函数进行重载工作。

你可以在global scope 或是在每个class内做这件事儿。

然而如果你决定运用这个机会,你必须知道,你正从根本层面改变整个游戏规则,因为从此“函数调用 语义”会取代“骤死式语义”,也就是说,如果你将operator&&重载,下面这个式子:

if (expressionl && expression2)

会被编译器视为以下两者之一:

if (expression1.operator&&(expression2))
// 假设 operator&& 是个 member function。

if (operator&&(expressionl, expression2))
// 假设operator&&是个全局函数。


这看起来没什么大不了,但是“函数调用”语义和所谓的“骤死式”语义有两个重大的区别。

  • 第一,当函数调用动作被执行,所有参数值都必须评估完成,所以当我们调用operator&&和operator||时,两个参数都已评估完成。换句话说没有什么骤死式语义。
  • 第二,C++语言规范并未明确定义函数调用动作中各参数的评估顺序,所以没办法知道expression1和expression2 哪个会先被评估。这与骤死式评估法形成一个明确的对比,后者总是由左向右评估其自变量。

所以,如果你将&&或||重载,就没有办法提供程序员预期(甚至依赖)的某种行为模式。所以请不要重载&&或||。

逗号(,)操作符的情况类似,但是在探究它之前,我要先暂停一下,让你调匀你那乱掉了的呼吸:“逗号操作符?哦?有所谓的逗号操作符吗?”是的,有!

逗号操作符用来构成表达式,你应该已经在 for 循环的更新区 (update part)见过此物。

举个例子,以下函数以 Kemighan 和 Ritchie 合著的经典作品 The C Programming Language 第二版(Prentice-Hall,1988)为本:

//将字符串 s的字符顺序颠倒。
void reverse (char s[])
{
for(int i=0,j=strlen(s)-1;i<j;++i,--j)//啊哈,用到了逗号操作符!
{
int c=s[i];
s[i]=s[j];
s[j]=c;
}

在这里,for 循环的最后一个成分中,i被累加而j被递减。

这里很适合使用逗号操作符,因为for 循环的最后一个成分必须是个表达式(expression);如果用个别语句(statements)来改变i和j的值,是不合法的。

C++有一些规则用来定义&&和||面对内建类型的行为,C++同样也有一些规则用来定义逗号操作符面对内建类型的行为。

表达式如果内含逗号,那么逗号左侧会先被评估,然后逗号的右侧再被评估;最后,整个逗号表达式的结果以逗号右侧的值为代表。

所以面对上述循环的最后一个成分,编译器首先评估++i,然后是--j,而整个逗号表达式的结果是--j的返回值。

或许你会奇怪为什么你需要知道这些。是的,你需要知道,因为如果你打算撰写自己的逗号操作符,就必须模仿这样的行为。不幸的是,你无法执行这些必要的模仿。

如果你把操作符写成一个non-member function,你绝对无法保证左侧表达式一定比右侧表达式更早被评估,因为两个表达式都被当做函数调用时的自变量,传递给该操作符函数,而你无法控制一个函数的自变量评估顺序。所以non-member 做法不可行。

唯一剩下的可能是将操作符写成一个member function。但即便如此你仍然不能保证逗号操作符的左操作数会先被评估,因为编译器并不强迫做这样的事情。因此你无法“不但将逗号操作符重载,并保证其行为像它应该有的那样”。所以不要轻率地将它重载。

你或许会疑惑,重载的疯狂行为到底有没有底线?毕竟,如果可以将逗号操作符
重载,还有什么是你不能重载的呢?事实证明有底线存在。

你不能够重载以下操作符:


(关于 new 和 delete operators,以及 operator new,operator delete,operator new[]和operator delete[],请参考条款8)

当然啦,只因为可以重载这些操作符,就毫无理由地去进行,是没有道理的。

操作符重载的目的是要让程序更容易被阅读、被撰写、被理解,不是为了向别人夸耀你知道“逗号其实是个操作符”。

如果你没有什么好理由将某个操作符重载,就不要去做。面对&&,||和,,实在难有什么好理由,因为不管你多么努力,就是无法令其行为像它们应有的行为一样。
 

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

单片机超声波测距+WTD588D语音播报的设计

第一章 绪论 1.1 课题设计目的及意义 1.1.1设计的目的 随着科学技术的快速发展&#xff0c;超声波在测距中的应用越来越广。但就目前的急速水平来说&#xff0c;人们可以具体利用的测距技术还十分有限&#xff0c;因此&#xff0c;这是一个正在蓬勃发展而又有无限前景的技术…

基于51单片机多功能太阳能充电器设计

1 绪论1.1 本课题研究背景及现状 当代社会随着一些不可再生资源如煤炭&#xff0c;石油等日益减少&#xff0c;使得各国社会经济越来越受能源问题的约制&#xff0c;因此许多国家开始逐渐的实行“阳光计划”&#xff0c;开发洁净的能源如太阳能&#xff0c;用以成为本国经济发…

C++多态总结与原理、菱形继承问题

文章目录 多态什么是多态 多态的定义及实现多态的构成条件虚函数 虚函数的重写虚函数重写的两个例外协变 重写C11 override 和 final重载、覆盖(重写)、隐藏(重定义)的对比 抽象类概念接口继承和实现继承小结 多态的原理虚函数表多态的原理动态绑定与静态绑定 单继承和多继承关…

数据结构之二叉树的超详细讲解(2)--(堆的概念和结构的实现,堆排序和堆排序的应用)

个人主页&#xff1a;C忠实粉丝 欢迎 点赞&#x1f44d; 收藏✨ 留言✉ 加关注&#x1f493;本文由 C忠实粉丝 原创 数据结构之二叉树的超详细讲解(2)--(堆的概念和结构的实现,堆排序和堆排序的应用) 收录于专栏【数据结构初阶】 本专栏旨在分享学习数据结构学习的一点学习笔记…

IC解析之TPS1HB08-Q1

目录 1.主要参数2. 接口定义3. 工作原理分析高低边驱动的作用TPS1HB08-Q1架构TPS1HB08-Q1典型应用电路参数设置 4.总结 1.主要参数 2. 接口定义 其中&#xff0c;不同的IC版本在故障反馈引脚有所差异&#xff0c;A/B版本则为ILIM功能&#xff0c;F版本则为FLT功能&#xff0c;两…

GpuMall智算云:QwenLM/Qwen1.5/Qwen1.5-7B-Chat

Qwen 是阿里巴巴集团 Qwen 团队的大型语言模型和大型多模态模型系列&#xff0c;现在大型语言模型已经升级到 Qwen1.5 版本。 GpuMall智算云 | 省钱、好用、弹性。租GPU就上GpuMall,面向AI开发者的GPU云平台 无论是语言模型还是多模态模型&#xff0c;都在大规模的多语言和多模…

【Python】 从Python列表中获取唯一值

基本原理 在Python中&#xff0c;列表是一种非常灵活的数据结构&#xff0c;它允许存储不同类型的元素。然而&#xff0c;有时我们可能需要从列表中提取唯一的值&#xff0c;即去除重复的元素。这在处理数据集或进行数据分析时尤其有用。Python提供了几种方法来实现这一目标。…

甘肃省大学生志愿服务西部计划报名流程及免冠证件照处理

在甘肃省&#xff0c;大学生志愿服务西部计划是一项旨在鼓励和引导大学生参与西部地区社会服务与发展的重要项目。随着2024年报名季的到来&#xff0c;许多有志青年正准备投身这一有意义的事业。本文将详细介绍报名流程&#xff0c;并提供免冠证件照的处理技巧&#xff0c;帮助…

人工智能——什么是摩尔定律以及它如何影响人工智能?

1. 概述 摩尔定律是现代技术发展中一个至关重要的基石。它预言了微芯片上晶体管的数量大约每两年翻一番&#xff0c;这一现象导致了计算能力的指数级增长。在过去的50多年里&#xff0c;这一定律一直是推动技术进步的强大动力&#xff0c;并且对人工智能领域产生了深远的影响。…

市面上前 11 名的 Android 数据恢复软件

Android数据恢复软件是恢复无意中删除的文件或文件夹的必要工具。该软件还将帮助您恢复丢失或损坏的信息。本文介绍提供数据备份和磁盘克隆选项的程序&#xff0c;这些选项有助于在Android设备上恢复文件的过程。 如果您正在寻找一种有效的方法来恢复图像&#xff0c;文档&…

宝塔Nginx设置图片访问跨域

宝塔Nginx设置图片访问跨域 针对某一个站点设置 找到对应的站点点击 “设置” 增加对应header设置 代码&#xff1a; location ~ .*\.(gif|jpg|jpeg|png|bmp|swf)${#允许跨域add_header Access-Control-Allow-Origin *;add_header Access-Control-Allow-Headers X-Requeste…

解密MySQL中的临时表:探究临时表的神奇用途

欢迎来到我的博客&#xff0c;代码的世界里&#xff0c;每一行都是一个故事 解密MySQL中的临时表&#xff1a;探究临时表的神奇用途 前言临时表的定义与分类创建与使用临时表临时表的操作与管理优化与性能提升注意事项与最佳实践 前言 在数据库管理中&#xff0c;临时表是一个…

Kali的基本扫描命令

nmap -sP 192.168.10.0/24 //扫描10网段存活的主机 nmap -P 192.168.10.142 //扫描主机开放的端口 nmap -sS 192.168.10.142 //TCP半开扫描 nmap -sT 192.168.10.142 //TCP全开扫描 nmap -O 192.168.10.142 //扫描靶机的操作系统类型 nmap -sV 192.168.10.142 //扫描开放端口对…

记一次绕过宝塔防火墙的BC站渗透

0x00 信息收集 由于主站存在云waf 一测就封 且初步测试不存在能用得上的洞 所以转战分站 希望能通过分站获得有价值的信息 这是一个查询代理帐号的站 url输入admin 自动跳转至后台 看这个参数 猜测可能是thinkCMF 0x01 getshell thinkcmf正好有一个RCE 可以尝试一下 ?afetc…

和可被k整除的子数组 ---- 前缀和

题目链接 题目: 分析: 补充知识 1. 同余定理: (a-b) % p 0即a-b能被p整除, > a % p b % p 2. c, java中 [负数 % 正数] 的结果是负数, 想要得到正确结果 > (a%pp)%p这道题和<和为k的子数组>类似, 利用前缀和的思想, 计算以i结尾的所有子数组, 前缀和为sum[i] …

React项目知识积累(四)

1.useMemo( ) 在 React 中&#xff0c;useMemo 是一个 Hook&#xff0c;用于记忆计算结果&#xff0c;只有当依赖项之一发生变化时&#xff0c;才会重新计算。这有助于避免不必要的计算和渲染&#xff0c;从而提高应用程序的性能。 基本语法如下&#xff1a; const memoized…

【ai】pycharm安装langchain 相关module

pycharm module install 【Python学习 】一篇文章教你PyCharm如何快速安装module 【python】pycharm如何安装python的模块包版本 2024.1.2 RC2 找到当前的虚拟项目 找到解释器 我现在配置为专门为openai-start 准备的3.10 版本+ 号可以找到模块

linux经典定时任务

在使用时记得替换为自己的脚本路径。请在相应的脚本第一行加上#!/bin/bash&#xff0c;否则脚本在定时任务中无法执行。 1、在每天凌晨2点执行 0 2 * * * /bin/sh bashup.sh 2、每天执行两次 下面的示例命令将在每天上午5点和下午5点执行。您可以通过逗号分隔指定多个时间戳…

基于双差分值和RR间隔处理的心电信号R峰检测算法(MATLAB R2018A)

心电信号中的R峰是确定心率和节律、以及检测其它波形特征点&#xff08;图1A&#xff09;的基础。R峰的准确检测是心率变异性分析、心拍分割和心律失常识别重要的处理步骤。 现有的心电信号R峰检测方法主要为基于规则的决策法和基于深度学习的检测方法。基于规则的决策法通常对…

全域运营平台的优缺点各有哪些?听听使用者怎么说!

作为多个创业者交流群内的热点话题&#xff0c;关于全域运营平台优缺点的分析和点评不断涌现&#xff0c;为许多创业者更多信息的同时&#xff0c;也让他们的选择过程变得非常艰难。而在众多的全域运营平台中&#xff0c;被分析和点评次数最多的&#xff0c;当属全域运营平台。…