C++ Primer 5th笔记(chap 14 重载运算和类型转换)算术和关系运算符

本文主要是介绍C++ Primer 5th笔记(chap 14 重载运算和类型转换)算术和关系运算符,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

运算符
双目算术运算符+ (加),-(减),*(乘),/(除),% (取模)
关系运算符==(等于),!= (不等于),< (小于),> (大于>,<=(小于等于),>=(大于等于)
  • 通常情况下,算术和关系运算符应该定义为非成员函数,以便两侧的运算对象进行转换。
  • 由于这些运算符一般不会改变运算对象的状态,所以形参都是常量引用。
  • 如果类同时定义了算数运算符和相关的复合赋值运算符,则通常情况下应该使用复合赋值来实现算数运算符。

1. 算术运算符

通常会计算它的两个运算对象并得到一个新值,这个值通常存储在一个局部变量内,操作完成后返回该局部变量的副本作为结果(返回类型建议设置为原对象的const类型)。

Sales_data operator +(const Sales_data &lhs,const Sales_data &rhs)
{Sales_data sum = lhs;sum += rhs;return sum;
}

2. 相等运算符(Equality Operators)

设计准则:

  • 如果类在逻辑上有相等性的含义,则应该定义operator==而非一个普通的命名函数。这样做便于使用标准库容器和算法,也更容易记忆。
  • 通常情况下,operator==应该具有传递性。
  • 如果类定义了operator==,则也应该定义operator!=。
  • operator==和operator!=中的一个应该把具体工作委托给另一个。
bool operator==(const Sales_data &lhs, const Sales_data &rhs)
{return lhs.isbn() == rhs.isbn() &&lhs.units_sold == rhs.units_sold &&lhs.revenue == rhs.revenue;
}bool operator!=(const Sales_data &lhs, const Sales_data &rhs)
{return !(lhs == rhs);
}

3. 赋值运算符

  • 不论形参的类型是什么,赋值运算符运算符都必须定义为成员函数,复合赋值运算符也通常如此。
  • 两类运算符都应该返回左侧运算对象的引用(赋值运算符和复合赋值运算符)。
  • 可以使用别的类型作为右侧运算对象
//重载赋值运算符
StrVec &StrVec::operator=(initializer_list<string> il)
{//alloc_copy分配内存空间,并从给定安慰内拷贝元素auto data=alloc_n_copy(il.begin(),il.end());free();  // 销毁对象中的元素并释放内存空间elements=data.frist;//更新数据成员,使其指向新空间first_free=cap=data.second; return *this;  } //复合赋值运算符 
// member binary operator: left-hand operand is bound to the implicit this pointer
// assumes that both objects refer to the same book
Sales_data& Sales_data::operator+=(const Sales_data &rhs)
{units_sold += rhs.units_sold;revenue += rhs.revenue;return *this;
}

4. 关系运算符(Relational Operators)

定义顺序关系。 eg. 关联容器中用到的小于运算符

  • 如果某个类在逻辑上有相等性的含义,则该类应该定义operator==。
  • 定义了相等运算符的类通常也会定义关系运算符。
  • 如果类定义了operator==,则关系运算符的定义应该与operator==保持一致。特别是,如果两个对象是不相等的,那么其中一个对象应该小于另一个对象。
  • 如果存在唯一一种可靠的<定义,则应该考虑为这个类定义<运算符。如果类同时还包含==,则当且仅当<的定义和==产生的结果一致时才定义<运算符。
//重载复合赋值运算符
StrVec &StrVec::operator+=(initializer_list<string> il)
{unit_sold+=rhs.units_sold;revenue+=rhs.revenue;return *this;
}

这篇关于C++ Primer 5th笔记(chap 14 重载运算和类型转换)算术和关系运算符的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/855315

相关文章

java中新生代和老生代的关系说明

《java中新生代和老生代的关系说明》:本文主要介绍java中新生代和老生代的关系说明,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、内存区域划分新生代老年代二、对象生命周期与晋升流程三、新生代与老年代的协作机制1. 跨代引用处理2. 动态年龄判定3. 空间分

从入门到精通C++11 <chrono> 库特性

《从入门到精通C++11<chrono>库特性》chrono库是C++11中一个非常强大和实用的库,它为时间处理提供了丰富的功能和类型安全的接口,通过本文的介绍,我们了解了chrono库的基本概念... 目录一、引言1.1 为什么需要<chrono>库1.2<chrono>库的基本概念二、时间段(Durat

C++20管道运算符的实现示例

《C++20管道运算符的实现示例》本文简要介绍C++20管道运算符的使用与实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧... 目录标准库的管道运算符使用自己实现类似的管道运算符我们不打算介绍太多,因为它实际属于c++20最为重要的

Visual Studio 2022 编译C++20代码的图文步骤

《VisualStudio2022编译C++20代码的图文步骤》在VisualStudio中启用C++20import功能,需设置语言标准为ISOC++20,开启扫描源查找模块依赖及实验性标... 默认创建Visual Studio桌面控制台项目代码包含C++20的import方法。右键项目的属性:

c++中的set容器介绍及操作大全

《c++中的set容器介绍及操作大全》:本文主要介绍c++中的set容器介绍及操作大全,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录​​一、核心特性​​️ ​​二、基本操作​​​​1. 初始化与赋值​​​​2. 增删查操作​​​​3. 遍历方

解析C++11 static_assert及与Boost库的关联从入门到精通

《解析C++11static_assert及与Boost库的关联从入门到精通》static_assert是C++中强大的编译时验证工具,它能够在编译阶段拦截不符合预期的类型或值,增强代码的健壮性,通... 目录一、背景知识:传统断言方法的局限性1.1 assert宏1.2 #error指令1.3 第三方解决

C++11委托构造函数和继承构造函数的实现

《C++11委托构造函数和继承构造函数的实现》C++引入了委托构造函数和继承构造函数这两个重要的特性,本文主要介绍了C++11委托构造函数和继承构造函数的实现,具有一定的参考价值,感兴趣的可以了解一下... 目录引言一、委托构造函数1.1 委托构造函数的定义与作用1.2 委托构造函数的语法1.3 委托构造函

C++11作用域枚举(Scoped Enums)的实现示例

《C++11作用域枚举(ScopedEnums)的实现示例》枚举类型是一种非常实用的工具,C++11标准引入了作用域枚举,也称为强类型枚举,本文主要介绍了C++11作用域枚举(ScopedEnums... 目录一、引言二、传统枚举类型的局限性2.1 命名空间污染2.2 整型提升问题2.3 类型转换问题三、C

C++链表的虚拟头节点实现细节及注意事项

《C++链表的虚拟头节点实现细节及注意事项》虚拟头节点是链表操作中极为实用的设计技巧,它通过在链表真实头部前添加一个特殊节点,有效简化边界条件处理,:本文主要介绍C++链表的虚拟头节点实现细节及注... 目录C++链表虚拟头节点(Dummy Head)一、虚拟头节点的本质与核心作用1. 定义2. 核心价值二

C++ 检测文件大小和文件传输的方法示例详解

《C++检测文件大小和文件传输的方法示例详解》文章介绍了在C/C++中获取文件大小的三种方法,推荐使用stat()函数,并详细说明了如何设计一次性发送压缩包的结构体及传输流程,包含CRC校验和自动解... 目录检测文件的大小✅ 方法一:使用 stat() 函数(推荐)✅ 用法示例:✅ 方法二:使用 fsee