14 重载运算和类型转换
14.1基本概念
14.2 基本输入输出运算符
14.3 算术和关系运算符
14.4 赋值运算符
14.5 下标运算符
14.6 递增和递减运算符
14.7 成员访问运算符
14.8 函数调用运算符
14.9 重载,类型转换,运算符
14.1 重载的运算符是具有特殊性质的函数, 他们的名字由关键字operator 和其后要定义的运算符号共同组成
规则
  • 不能为内置类型定义重置的运算符 类似 int operator +(int,int)不被允许
  • 只能重载现有的运算符
  • 优先级与原优先级保持一致
  • 对象:或者是类的成员,或者至少含有一个类类型的参数
  • 函数调用: data1 + data2 等价于 operator + (data1,data2)
  • 类似调用其它成员函数,利用.运算符或者->运算符etc: data1 += data2 等价于 data1.operator +=(data2 );
  • 一般情况下, 不应该重载的 逗号,取地址&,逻辑与&&逻辑或||
使用与内置类型一致的含义
  • IO
  • 检查相等性== !=
  • 单序 < >
  • 返回类型应该与内置版本的返回类型兼容:逻辑运算符和关系返回bool,算术类型返回类类型,赋值复合运算符返回左侧对象的引用
将重载运算符设置为成员和非成员
  • 赋值(=),下标([]),调用(()),和成员访问箭头(->),运算符必须是成员
  • 复合赋值运算符一般应该是成员,但并非必须
  • 改变对象状态和运算符或者与给定类型密切相关的运算符,如的递增,递减,和解引用运算符,通常应该是成员
  • 具有对称性的运算符可能转换任意一端的运算对象,例如算术,相等性,关系,位运算符,普通的非成员函数

etc :
string s = "world";
string t = s + "!";
string u = "hi" + s;//如果+ 是string的成员函数,就不会调用成功,因为"hi"不是string 而是const char ;
事实上, string 里面的+ 是普通的非成员函数,"hi" + s 变成了 operator+("hi",s) 与其它任何函数调用一样,每个实参都能被转换为形参类型
14.2 输入输出运算符
14.2.1 重载输出运算符 <<
  • 注意 输出运算符尽量减少格式化操作//即不要输出换行符
  • 输入输出运算符必须是非成员函数, 否则他们的左侧运算对象将是我们的类的一个对象,设置成为友元
输入运算符必须考虑输入失败的情况,
  • 含有错误类型的数据
  • 到达文件结尾,遇到输入流
  • 检查, 等输入完毕, 赶在使用这些数据前一次性检查
下标运算符 [ ]
  • 下标函数返回的都是引用
  • 下标函数必须是成员函数
  • 定义下标函数的常量和非常量函数(用以决定返回常量还是变量的引用)
++和–运算符
operator ++(),operator –()
后置 operator ++(int);
operator –(int);
显示调用运算符函数 StrBlobPtr p(a1);
p.operator++(0) ;//使用后置版本的operator++
p.operator++(1);//使用前置版本的operator–
14.7 成员访问运算符
在迭代器及智能指针类中常常用到解引用运算符(),和箭头运算符(->)
std::string &operator ()const
std::string &operator ->()const
{
return &( this->operator ());//对*解引用运算符的调用 ,因为*this是
}
->运算符永远都不能丢掉最根本的属性, 成员访问,当我们重载箭头时,可以改变的是从那个对象当中获取成员,而箭头获取成员这一事实永远不变.
对于形如 point->mem 的表达式来说,point必须是指向类对象的指针或者了是一个重载了operator->的类的对象,根据point类型的不同,point->mem 分别等价于
(*point).mem //point是一个内置的指针类型
point.operator()->mem //point 是类的一个对象
除此之外,代码都将发生错误,point->mem的执行过程如下表示:
1 如果point是指针,则我们应用内置的箭头运算符
2 如果point 是定义了operator-> 的类的对象,则我么使用point.operator->()的结果来获取mem,其中,如果该结果是一个指针,则执行第一步;如果该结果本身含有了重载的operator ->() 则重复调用当前步骤,,最终,当这一程序结束时程序或者返回所需的内容,或者返回一些表示程序错误的信息//疑问甚多
14.8 函数调用运算符
定义了调用运算符的对象称为函数对象
含有状态的函数对象类,