[C++] 重载运算符与类型转换(1)
//定义
ostream& operator<<(ostream &os, const Sales_data &item) {
os << item.isbn() <<" "<<item.units_sold<< "——重载输出运算符";
return os;
}
friend ostream& operator<<(ostream&, const Sales_data&);
friend istream& operator >> (istream&, Sales_data&);
6、重载输入运算符
//重载输入运算符
istream& operator >> (istream &is, Sales_data &item) {
double price;
is >> item.bookNo >> item.units_sold >> price;
if (is) //检查输入是否成功
item.revenue = item.units_sold*price;
else
item = Sales_data();//输入失败:对象赋予默认状态
return is;
}
调用
/*重载运算符操作,调用*/
Sales_data sales_data;
operator >> (cin, sales_data);//输入
operator<< (cout, sales_data)<<endl;//输出
1)输入运算符必须处理输入可能失败的情况,而输出运算符不需要
//相等运算符——包括相等和不等判断,要求所有数据成员对应相等
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_n_copy分配内存空间并从给定范围内靠背元素
auto data = alloc_n_copy(il.begin(), il.end());
free();
elements = data.first;
first_free = cap = data.second;
return *this;
}
2)复合赋值运算符定义在类的内部,两者都返回左侧运算对象的引用
//复合赋值运算符
Sales_data& Sales_data::operator+=(const Sales_data &rhs) {
units_sold += rhs.units_sold;
revenue += rhs.revenue;
return *this;
}
//算数运算符--返回对象的拷贝
Sales_data operator+(const Sales_data &lhs, const Sales_data &rhs) {
Sales_data sum = lhs;
sum += rhs;
return sum;
}
//下标运算符
string& StrVec::operator[](size_t n) {
return elements[n];
}
const string& StrVec::operator[](size_t n) const{
return elements[n];
}
StrBlobPtr& StrBlobPtr::operator++() {
check(curr,"increment past end of StrBlobPtr");//如果已经指向了容器的尾后位置,那么无法继续递增它
++curr;
return *this;
}
StrBlob& StrBlobPtr::operator--() {
--curr;
check(curr, "decrement past end of StrBlobPtr");
return *this;
}
//后置递增和递减
StrBlobPtr StrBlobPtr::operator++(int) {
StrBlobPtr ret = *this;
++(*this);//调用前置的操作
return ret;
}
StrBlobPtr StrBlobPtr::operator--(int) {
StrBlobPtr ret = *this;
--(*this);
return ret;
}
3)调用
//重载前置和后置递增递减运算符
StrBlobPtr p;
p.operator++();//调用后置运算符
p.operator++();//调用前置运算符
//成员访问运算符
string& StrBlobPtr::operator*()const {
auto p = check(curr, "dereference past end");
return (*p)[curr];
}
string* StrBlobPtr::operator->()const {
//将实际工作委托给解引用运算符
return &(this->operator*());
}
[C++] 重载运算符与类型转换(1)的更多相关文章
- C++ Primer : : 第十四章 : 重载运算符与类型转换之类型转换运算符和重载匹配
类型转换运算符 class SmallInt { public: SmallInt(int i = 0) : val(i) { if (i < 0 || i > 255) throw st ...
- [C++ Primer] : 第14章: 重载运算符与类型转换
基本概念 重载运算符是具有特殊名字的函数: 它们的名字由关键字operator和其后要定义的运算符号共同组成. 重载运算符函数的参数数量与该运算符作用的运算对象数量一样多. 对于二元运算符来说, 左侧 ...
- 【C++】C++中重载运算符和类型转换
输入输出运算符 输入输出运算符 输入输出运算符 算术和关系运算符 相等运算符 关系运算符 赋值运算符 复合赋值运算符 下标运算符 递增和递减运算符 成员访问运算符 函数调用运算符 lambda是函数对 ...
- [C++] 重载运算符与类型转换(2)——函数调用运算符和类型转换运算符
1.这两个应该是C++中比较高级的用法了. 一.函数调用运算符 1.重载函数调用运算符(),必须是成员函数,一个类可以定义多个不同版本的调用运算符,相互之间应该在参数数量或者类型上有所区别. ...
- C++ Pirmer : 第十四章 : 重载运算符与类型转换之函数调用运算符与标准库的定义的函数对象
函数调用运算符 struct test { int operator()(int val) const { return (i > 0 ? i : -i); } }; 所谓的函数调用就是一个类重 ...
- c/c++ 重载运算符 类型转换运算符
重载运算符 类型转换运算符 问题:能不能把一个类型A的对象a,转换成另一个类型B的对象b呢?? 是可以的.这就必须要用类型A的类型转换运算符(conversion operator) 下面的opera ...
- C/C++ 运算符重载、数据类型转换
1.运算符就是“+”.“>>”等符号,对运算符重载实质就是对函数的重载,这样运算符就能在原有基础上增加新功能,不能自己定义新运算符,只能对已有运算符重载,重载运算符后不能改变运算符本身的特 ...
- # c++运算符重载之 前置++, 后置++, 负号运算符, 类型转换函数, 以及输入输出运算符
c++运算符重载之 前置++, 后置++, 负号运算符, 类型转换函数, 以及输入输出运算符 标签(空格分隔): c++ 前言 我在c++学习的过程中, 对这几个不太常见的运算符重载不太会写.出现了很 ...
- C++ Primer : 第十四章 : 重载运算与类型转换之重载运算符
重载前须知 重载运算符是特殊的函数,它们的名字由operator和其后要重载的运算符号共同组成. 因为重载运算符时函数, 因此它包含返回值.参数列表和函数体. 对于重载运算符是成员函数时, 它的第一个 ...
随机推荐
- Delegate,Block,Notification, KVC,KVO,Target-Action
Target-Action: 目标-动作机制,所有的UIControl及子类都是这个机制:原理:在对象产生某个事件的特定时刻,给一个对象发送一个消息:类内部target去执行action方法 Dele ...
- Laravel框架内实现api文档:markdown转为html
前后端分离的工作模式于今是非常流行了,前后端工作的对接,就离开不了API文档的辅助. 根据自己以往的工作经历,以及了解的一些资讯,API文档的建立,无非以下几种方式: 1. word文档模板 2. 第 ...
- 那些必会用到的 ES6 精粹
前言 最新的 ECMAScript 都已经到发布到 2019 版了. 我们应该有的态度是: Stay hungry ! Stay young ! 从接触 vue 到工作中用到 vue 将近 2 年了, ...
- day0203
day02 1.for i in range() --->用于设置for循环的迭代设置. ranage 也是一个前闭后开的. 2.random.randrange() --->随机产生给予 ...
- Redis学习总结(六)--Redis集群伸缩
我们在上一章讲了如何创建集群,今天我们来实现下集群的伸缩. 添加节点 操作流程 1.启动节点 2.将节点加入到集群中 3.将数据槽从原来的节点迁移部分到新节点上 实践 1)准备两个新节点并启动 [ro ...
- python学习——函数参数
一.为什么要使用函数 函数能提高应用的模块性,和代码的重复利用率. 二.函数的参数 位置参数:从左至右进行匹配 一般情况,也就是我们迄今为止最常用的方法,是通过位置进行匹配把参数值传递给函数头部的参数 ...
- egret之移除带参数的监听事件
this.selectBtn.addEventListener(egret.TouchEvent.TOUCH_TAP, this.onClickNewIndo.bind(this,this.data) ...
- ASP.NET Core实现对象自动映射-AgileMapper
我们为什么要在对象之间做映射 处于耦合性或者安全性考虑或者性能考虑我们不希望将Model模型传递给他们,我们会在项目中创建一些DTO(Data transfer object数据传输对象),进行数据的 ...
- 五月月赛 寻宝 exkmp + 主席树
: 寻宝 时间限制: Sec 内存限制: MB 提交: 解决: [提交] [状态] [讨论版] [命题人:admin] 题目描述 采蘑菇的小西佬找到了一张上古年间的藏宝图,上面画着m座连绵不断的山,他 ...
- P3705 [SDOI2017]新生舞会 分数规划 费用流
#include <algorithm> #include <iterator> #include <iostream> #include <cstring& ...