1、除了函数调用符之外,重载操作符的形参数目(包括成员函数的隐式this指针)与操作符的操作数目相同。函数调用操作符可以接受任意数目的操作数。

表1 可重载的操作符名

+

-

*

/

%

^

&

|

~

!

,

=

<

>

<=

>=

++

--

<<

>>

==

!=

&&

||

+=

-=

/=

%=

^=

&=

|=

*=

<<=

>>=

[]

()

->

->*

new

new[]

delete

delete []

表2 不能重载的操作符

::

.*

.

?:

不能通过连接其他合法符号来创建任何新的操作符。

2、重载操作符必须具有一个类类型/枚举类型操作数。不能改变内置操作符原有的优先级和结合性。除了函数调用操作符operator()之外,重载操作符时使用默认实参是非法的。

3、作为成员函数的操作符有一个隐含的this指针,限定为第一个操作数。

4、一般将算术和关系操作符定义为非成员函数,而将赋值操作符定义为成员。

5、加返回右值,而复合赋值返回对左操作数引用。

6、重载的设计

1)不要重载具有内置含义的操作符

赋值操作符(可定义自己的)、取地址操作符和逗号操作符对类类型操作数有默认含义。内置逻辑与(&&)和逻辑或(||)操作符使用短路求值,如果重新定义该操作符,将失去操作符的短路求值特征。

2)用作关联容器键类型的类就有<操作符,顺序容器中应定义==操作符。为了相应算法操作的方便。如sort,find等。

3)总结

• 赋值(=)、下标([])、调用(())和成员访问箭头(->)等操作符必须定义为成员,将这些操作符定义为非成员函数将在编译时标记为错误。

• 像赋值一样,复合赋值操作符通常应定义为类的成员,与赋值不同的是,不一定非得这样做,如果定义非成员复合赋值操作符,不会出现编译错误。

• 改变对象状态或与给定类型紧密联系的其他一些操作符,如自增、自减和解引用,通常就定义为类成员。

• 对称的操作符,如算术操作符、相等操作符、关系操作符和位操作符,最好定义为普通非成员函数。

7、重载操作符的定义示例

1)输出<<

示例

ostream& operator<<(ostream& os, const ClassType *object)
{//...os << //...return os;
}

通常所做格式化应尽量少。

IO操作符必须为非成员函数,否则会出现 item << cout的这种不自然情形。

2)输入>>

输入操作符必须处理错误和文件结束的可能性。

示例

istream& operator>>(istream& in, Sales_Item& s)
{double price;in >> s.isbn >> s.units_sold >> price;if (in)s.revenue = s.units_sold * price;elses = Sales_item(); //input failed:reset object to default statereturn in;
}

通常输入操作符仅需设置failbit,设置eofbit意思是文件耗尽,设置badbit指出流被破坏。

3)算术操作符和关系操作符

示例

Sales_item operator+(const Salse_item& lhs, const Salse_item& rhs)
{Sales_item ret(lhs);ret += rhs;  //非常好用的方法return ret;
}

4)相等操作符与不等操作符一起实现

示例

inline bool
operator==(const ClassType &lhs, const ClassType &rhs)
{return ...
}
inline bool
operator!=(const ClassType &lhs, const ClassType &rhs)
{return !(lhs == rhs);
}

5)一般而言,赋值操作符与复合赋值操作符应返回左操作数的引用(*this)。

6)下标操作符

定义两个版本:一个为非const成员并返回引用,另一个为const成员并返回const引用。

示例

class Foo
{
public:int &operator[](const size_t);const int &operator[](const size_t) const;//...
private:vector<int> data;
};int& Foo::operator[](const size_t index)
{return data[index]; //注意,这里没有进行下标越界检查
}
const int& Foo::operator [](const size_t index) const
{return data[index];
}

7)成员访问操作符

同样,也是两个版本。

重载箭头操作符必须返回指向类类型的指针,或返回定义了自己的箭头操作符的类类型对象(或引用)。

示例

#include "iostream"
#include "stdio.h"
using namespace std;
class ScreenPtr;
class Screen //用于ScreenPtr中操作对象的类
{
public:Screen(){cout << "In Screen" << endl;}void display(){cout << "In Screen Display" << endl;}
};
class ScrPtr //智能指针,用来管理ScreenPtr类中要操作对象的类的指针
{friend class ScreenPtr;Screen *sp;size_t use;ScrPtr(Screen *p):sp(p), use(1) {}~ScrPtr() {delete sp;}
};class ScreenPtr
{
public:ScreenPtr(Screen *p):ptr(new ScrPtr(p)) {}ScreenPtr(const ScreenPtr &orig):ptr(orig.ptr) //复制构造函数{++ptr->use;}ScreenPtr& operator=(const ScreenPtr&){}~ScreenPtr(){if (--ptr->use == 0){delete ptr;}cout << "In ScreenPtr" << endl;}
public:Screen& operator*(){return *ptr->sp;}Screen* operator->(){return ptr->sp;}const Screen& operator*() const{return *ptr->sp;}const Screen* operator->() const{return ptr->sp;}
private:ScrPtr *ptr;
};int main()
{Screen *myscreen = new Screen();ScreenPtr p(myscreen);p->display();return 0;
}

说明:point->action();

1.If point is a pointer to a class object that has a member named action , then

the compiler writes code to call the action member of that object.

2.Otherwise, if point is an object of a class that defines operator-> , then

point->action is the same as point.operator->()->action . That is, we execute

operator->() on point and then repeat these three steps, using the result of

executing operator-> on point .

3. Otherwise, the code is in error.

20、C++ Primer 4th 笔记,重载运算符(1)相关推荐

  1. 42、C++ Primer 4th笔记,IO库,未格式化IO操作

    1.标准库还提供了丰富的支持未格式化IO的低级操作,这些操作使我们能够将流作为未解释的字节序列处理,而不是作为数据类型(如char,int,string等)的序列处理. 2.单字节操作 几个未格式化的 ...

  2. 37、C++ Primer 4th笔记,特殊工具与技术,类成员指针

    1.成员指针(pointer to member)包含类的类型以及成员的类型.成员指针只应用于类的非static成员.static类成员不是任何对象的组成部分,所以不需要特殊语法来指向static成员 ...

  3. 29、C++ Primer 4th 笔记,异常处理

    1.类成员的指针不同于指向普通数据或函数的指针,普通指针只根据对象或函数的类型而变化,而成员的指针必须反映成员所属的类. 2.异常是通过抛出对象而引发的.该对象的类型决定应该激活哪个处理代码.被选中的 ...

  4. 24、C++ Primer 4th 笔记,面向对象编程(2)

    1.每个派生类对象包含一个基类部分.因此派生类对象也是基类对象.可以将派生类对象的引用转换为基类子对象的引用,同理指针. 2.没有从基类引用(或基类指针)到派生类引用(或派生类指针)的(自动)转换. ...

  5. 38、C++ Primer 4th笔记,特殊工具与技术,嵌套类

    1.在一个类内部再定义另外一个类,这样的类称为嵌套类(nested class),也称为嵌套类型(nested type).嵌套类最常用于执行类. 嵌套类是独立的类,基本上与它们的外围类不相关,因此, ...

  6. C++ Primer 5th笔记(chap 14 重载运算和类型转换)函数匹配与重载运算符

    如果一个类既提供了转换目标是算术类型的类型转换,也提供了重载的运算符,则将会遇到重载运算符与内置运算符的二义性问题. 如果a是一种类型,表达式 a sym b 可能是: //不能通过调用形式来区分当前 ...

  7. 【C++笔记】运算符重载

    运算符重载的目的是对已有的运算符重新定义,赋予其另一种功能,以适应不同的数据类型. 一.加号运算符重载 作用:实现两个自定义数据类型的加法运算 1.1 通过成员函数重载+号 例: class Pers ...

  8. (C++学习笔记七)运算符重载

    九.运算符重载 1.Code : #include<iostream> using namespace std;//运算符重载的意义: //对已有的 运算符 重新进行定义,赋予其另一项功能 ...

  9. 北大郭炜《程序设计与算法(三)》Mooc笔记:运算符重载和继承

    文章目录 运算符重载 运算符重载的基本概念 赋值运算符的重载 为什么引入赋值运算符重载? 浅拷贝和深拷贝 对operator=返回值的讨论 复制构造函数的相同困境 运算符重载为友元函数 实例:可变长数 ...

最新文章

  1. java map collection_java 集合----Map、Collection
  2. 大数据算法系列——布隆过滤器
  3. C++简单使用priority_queue
  4. fisher判别_经典模式识别:Fisher线性判别
  5. .NET Core log4net 使用(转贴)
  6. 【代码源 Div1 - 109】#454. Minimum Or Spanning Tree(最小生成树,边权按位或,贪心,并查集) CF1624G
  7. windows版本和Linux版本的ffmpeg下载使用方法
  8. 老师用计算机教我们画画拼音,《汉语拼音13 ang eng ing ong》第三课时教学设计...
  9. 深圳:由“独角兽”们构建起的硬核科技之城
  10. VS2013使用技巧汇总
  11. 170713 逆向-填数游戏
  12. 5OSPF的邻居和NBMA环境下的邻居
  13. springcloud官方文档,中英文双版
  14. java如何解压rar文件怎么打开,Java压缩与解压rar文件
  15. 导入mdf文件的两种方法
  16. JAVA基础核心技术总结(2)--基本语法
  17. Praat脚本-028 | 批量合并目录内的音频文件
  18. EXCEL表格-根据身份证号计算性别、年龄(IF、MOD函数)
  19. 【Codeforces 1118D1】Coffee and Coursework (Easy version)
  20. Shakira feat Lil Wayne - Give it up to me

热门文章

  1. 9. 设计二个函数分别计算sinx和cosx_Excel技巧篇(一):超级好用的几个函数
  2. python 分类变量xgboost_用于可解释机器学习的四个Python库
  3. 查询中接受的主体参数_【自动化/测开面试集锦系列】SQL查询
  4. vue 拷贝 数组_vue源码中值得学习的方法
  5. JavaScript replace()
  6. Eclipse的.properties文件输出中文成unicode编码
  7. 为什么华为a1路由器网速变慢_路由器需要每天都关吗?看完专家的解释恍然大悟...
  8. 人工神经网络理论、设计及应用_红层软岩大直径素混凝土置换桩复合地基设计理论及应用研究——以成都 ICON云端项目为例...
  9. 开了立体声混音仍然不能内录_相位表是如何为你的混音工作带来帮助的
  10. 聚类算法实践——PCCA、SOM、Affinity Propagation