C++ Primer 5th笔记(chap 14 重载运算和类型转换)重载运算概述

1. 定义

重载运算是具有特殊名字的函数,它们的名字由关键字operator和其后要定义的运算符号组成。

2. 运算符表

2.1 可重载运算符

运算符类型 运算符种类
双目算术运算符 + (加),-(减),*(乘),/(除),% (取模)
关系运算符 ==(等于),!= (不等于),< (小于),> (大于>,<=(小于等于),>=(大于等于)
逻辑运算符 //(逻辑或),&&(逻辑与),!(逻辑非)
单目运算符 + (正),-(负),*(指针),&(取地址)
自增自减运算符 ++(自增),–(自减)
位运算符 / (按位或),& (按位与),~(按位取反),^(按位异或),,<< (左移),>>(右移)
赋值运算符 =, +=, -=, *=, /= , % = , &=, /(其实是竖着的)=, ^=, <<=, >>=
空间申请与释放 new, delete, new[ ] , delete[]
其他运算符 ()(函数调用),->(成员访问),,(逗号),

2.2 不可重载的运算符列表

运算符 含义
. 成员访问运算符
., -> 成员指针访问运算符
:: 域运算符
sizeof 长度运算符
?: 条件运算符
# 预处理符号

3. 重载运算符的设计规则

规则1

  • 不能改变内置类型的运算符的含义。
  • 只能重载已有的运算符,而不能发明新的运算符号。
  • 重载运算符的优先级和结合律跟对应的内置运算符保持一致。

规则2

  • 通常情况下,不应该重载逗号,、取地址&、逻辑与&&和逻辑或||运算符。
  • 如果类中含有算术运算符或位运算符,则最好也提供对应的复合赋值运算符。
  • 如何有==,一般会有!=
  • 如果有单序比较,则应该有operator<,同时也应该有> 和其他的。
  • 逻辑运算符返回bool,算术运算符返回类类型,赋值运算符和复合赋值运算符返回左侧运算对象的一个引用

4. 重载运算符的参数

参数表示运算符的运算对象,对于二元运算符来说,左侧运算对象传递给第一个参数,右侧运算对象传递给第二个参数。

eg.

data1 + data2
operator+(data1, data2);
data1 += data2;             // expression-based ''call''
data1.operator+=(data2);    // equivalent call to a member operator function
  • 除了重载的函数调用运算符operator()之外,其他重载运算符不能含有默认实参。
  • 重载运算符函数的参数数量和该运算符作用的运算对象数量一样多。
  • 成员运算符函数的显式参数数量比运算对象的数量少一个。

5. 设计为成员函数还是普通函数

  • 把运算符定义为成员函数时,它的左侧运算对象必须是运算符所属类型的对象。
  • 如果一个运算符函数是类的成员函数,则它的第一个运算对象会绑定到隐式的this指针上。
string s = "world";
string t = s + "!";     // ok: we can add a const char* to a string
string u = "hi" + s;    // would be an error if + were a member of string

如何选择将运算符定义为成员函数还是普通函数:

  • 赋值=、下标[]、调用()和成员访问箭头->运算符必须是成员函数。
  • 复合赋值运算符一般是成员函数,但并非必须。
  • 改变对象状态或者与给定类型密切相关的运算符,如递增、递减、解引用运算符,通常是成员函数。
  • 具有对称性的运算符可能转换任意一端的运算对象,如算术、相等性、关系和位运算符,通常是普通函数。

猜你喜欢

转载自blog.csdn.net/thefist11cc/article/details/113927839