非常感激我队友大爹给我的复习资料

您可以重定义或重载大部分 C++ 内置的运算符。这样,您就能使用自定义类型的运算符。

重载的运算符是带有特殊名称的函数,函数名是由关键字 operator 和其后要重载的运算符符号构成的。与其他函数一样,重载运算符有一个返回类型和一个参数列表。

1
Box operator+(const Box&);

声明加法运算符用于把两个 Box 对象相加,返回最终的 Box 对象。大多数的重载运算符可被定义为普通的非成员函数或者被定义为类成员函数。如果我们定义上面的函数为类的非成员函数,那么我们需要为每次操作传递两个参数,如下所示:

1
Box operator+(const Box&, const Box&);

示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
#include <iostream>
using namespace std;

class Box {
public:
double getVolume(void) {
return length * breadth * height;
}
Box(double l, double b, double h) : length(l), breadth(b), height(h) {}
Box operator+(const Box& b) {
return Box(length + b.length, breadth + b.breadth, height + b.height);
}
private:
double length; // 长度
double breadth; // 宽度
double height; // 高度
};

// 程序的主函数
int main() {
Box Box1(6.0, 7.0, 5.0);
Box Box2(12.0, 13.0, 10.0);
double volume = 0.0; // 把体积存储在该变量中
// Box1 的体积
volume = Box1.getVolume();
cout << "Volume of Box1 : " << volume << endl;
// Box2 的体积
volume = Box2.getVolume();
cout << "Volume of Box2 : " << volume << endl;
// 把两个对象相加,得到 Box3
Box Box3 = Box1 + Box2;
// Box3 的体积
volume = Box3.getVolume();
cout << "Volume of Box3 : " << volume << endl;
return 0;
}

/*
==============================
Volume of Box1 : 210
Volume of Box2 : 1560
Volume of Box3 : 5400
==============================
*/

可重载运算符 / 不可重载运算符

下面是可重载的运算符列表:

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

下面是不可重载的运算符列表:

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

运算符重载为成员函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
#include <iostream>
using namespace std;

class Complex{
private:
double real;
double imag;
public:
Complex (double r, double i) : real(r), imag(i) {}
Complex operator+ (const Complex& b) { //雷内实现
return Complex(real + b.real, imag + b.imag);
}
Complex operator- (const Complex& b);
void display();
};

Complex Complex::operator- (const Complex& b) { //类外实现
return Complex(real - b.real, imag - b.imag);
}
void Complex::display() {
cout << "( " << real << ", " << imag << " )" << endl;
}

int main(void){
Complex sb(23.2, 4.5);
Complex nt(12.4, 13.4);
Complex a = sb + nt;
Complex b = sb - nt;
a.display();
b.display();
return 0;
}
/*
================
( 35.6, 17.9 )
( 10.8, -8.9 )
================
*/

运算符重载为非成员函数

必须使用非成员函数的情况:

  • 要重载的操作符的第一个操作数不是可以更改的类型。如<<运算符的第一个操作数的类型为ostream, 是标准库的类型, 无法向其中添加成员函数
  • 以非成员函数形式重载, 支持更加灵活的类型转换。3.1 + c1就会以operator + (Complex(3.1), c1)的方式来执行, 从而支持了复数和实数的相加。

而以成员函数重载时, 左操作数必须具有Complex类型, 不能是实数(因为调用成员函数的目的对象不会被隐含转换),只有右操作数可以是实数(因为右操作数是函数的参数, 可以隐含转换)。

示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
#include <iostream>
using namespace std;

class Complex{
private:
double real;
double imag;
public:
Complex(double r = 0.0, double i = 0.0) : real(r), imag(i) {}
friend Complex operator + (const Complex& c1, const Complex& c2);
friend Complex operator - (const Complex& c1, const Complex& c2){
return Complex(c1.real-c2.real, c1.imag-c2.imag);
}
friend ostream& operator << (ostream& out, const Complex& c);
};

Complex operator + (const Complex& c1, const Complex& c2){
return Complex(c1.real+c2.real, c1.imag+c2.imag);
}

ostream & operator << (ostream& out, const Complex& c){
out << "( " << c.real << ", " << c.imag << " )";
return out;
}

int main(void){
Complex c1(5, 4), c2(2, 10), c3, c4;
cout << "c1 = " << c1 << endl;
cout << "c2 = " << c2 << endl;
c3 = c1 - c2;
cout << "c3 = c1 - c2 = " << c3 << endl;
c3 = c1 + c2;
cout << "c3 = c1 + c2 = " << c3 << endl;
c4 = 3.1 + c1;
cout << "c4 = 3.1 + c1 = " << c4 << endl;

return 0;
}

/*
===============================
c1 = ( 5, 4 )
c2 = ( 2, 10 )
c3 = c1 - c2 = ( 3, -6 )
c3 = c1 + c2 = ( 7, 14 )
c4 = 3.1 + c2 = ( 8.1, 4 )
===============================
*/

一元运算符

负号(-),逻辑非运算符(!),

以负号为例子,注意类的成员变量必须发生变化,因为一元运算不一定会有赋值操作,若不改变类的成员变量就会发生错误。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
#include <iostream>
using namespace std;

class Distance {
private:
int feet; // 0 到无穷
int inches; // 0 到 12
public:
// 所需的构造函数
Distance(int f, int i) {
feet = f;
inches = i;
}
// 显示距离的方法
void displayDistance() {
cout << "F: " << feet << " I:" << inches << endl;
}
// 重载负运算符( - )
Distance operator- () {
feet = -feet;
inches = -inches;
return *this;
}
};

int main() {
Distance D1(11, 10), D2(-5, 11);
-D1; // 取相反数
D1.displayDistance(); // 距离 D1
-D2; // 取相反数
D2.displayDistance(); // 距离 D2
return 0;
}

/*
==============================
F: -11 I:-10
F: 5 I:-11
==============================
*/

二元运算符

二元运算符需要两个参数,下面是二元运算符的实例。我们平常使用的加运算符( + )、减运算符( - )、乘运算符( * )和除运算符( / )都属于二元运算符。就像加 (+) 运算符。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
// 重载加运算符( + )
Distance operator+ (const Distance& b) {
return Distance(feet + b.feet, inches + b.inches);
}
// 重载减运算符( - )
Distance operator- (const Distance& b) {
return Distance(feet - b.feet, inches - b.inches);
}

int main() {
Distance D1(11, 10), D2(-5, 11);
Distance D3 = D1 + D2;
D3.displayDistance();
D3 = D1 - D2;
D3.displayDistance();
return 0;
}

/*
===================
F: 6 I:21
F: 16 I:-1
===================
*/

关系运算符

C++ 语言支持各种关系运算符( <、> 、 <= 、 >= 、 == 等等),它们可用于比较 C++ 内置的数据类型。

您可以重载任何一个关系运算符,重载后的关系运算符可用于比较类的对象。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
// 重载小于运算符( < )
bool operator< (const Distance& b) {
if (feet < b.feet)
return true;
else if (feet == b.feet && inches < b.inches)
return true;
else return false;
}

int main() {
Distance D1(11, 10), D2(-5, 11);
if (D1 < D2) {
cout << "D1 < D2" << endl;
}
else {
cout << "D1 >= D2" << endl;
}
return 0;
}

/*
=========
D1 >= D2
=========
*/

输入输出运算符

C++ 能够使用流提取运算符 >> 和流插入运算符 << 来输入和输出内置的数据类型。您可以重载流提取运算符和流插入运算符来操作对象等用户自定义的数据类型。

在这里,有一点很重要,我们需要把运算符重载函数声明为类的友元函数,这样我们就能不用创建对象而直接调用函数。

下面的实例演示了如何重载提取运算符 >> 和插入运算符 <<。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
// 重载输入运算符( >> )
friend istream& operator>> (istream& input, Distance &D) {
cin >> D.feet >> D.inches;
return input;
}
// 重载输出运算符( << )
friend ostream& operator<< (ostream& output, Distance &D) {
cout << "F: " << D.feet << " " << "I: " << D.inches << endl;
return output;
}

int main() {
Distance D1, D2;
cin >> D1 >> D2;
cout << D1 << D2 << endl;
return 0;
}

/*
======================
(input) 11 10 -5 11
F: 11 I: 10
F: -5 I: 11
======================
*/

递增递减运算符

递增运算符( ++ )和递减运算符( – )是 C++ 语言中两个重要的一元运算符。

注意,int 在 括号内是为了向编译器说明这是一个后缀形式,而不是表示整数。

前缀形式重载调用 Distance operator ++ () ,后缀形式重载调用 Distance ++ (int)。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
Distance operator++ (int) {
feet++;
inches++;
return *this;
}
// 前缀递减运算符 (--x)
Distance operator-- () {
--feet;
--inches;
return *this;
}

int main() {
Distance D1(11, 10), D2(-5, 11);
D1++, --D2;
D1.displayDistance();
D2.displayDistance();
return 0;
}

/*
==============
F: 12 I:11
F: -6 I:10
==============
*/

赋值运算符

就像其他运算符一样,您可以重载赋值运算符( = ),用于创建一个对象,比如拷贝构造函数。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
// 重载赋值运算符( = )
void operator= (const Distance& b) {
feet = b.feet;
inches = b.inches;
}
//重载加等于运算符 ( += )
void operator+= (const Distance& b) {
feet += b.feet;
inches += b.inches;
}

int main() {
Distance D1(11, 10), D2(-5, 11);
D1 = D2;
D1.displayDistance();
D1 += D2;
D1.displayDistance();
return 0;
}

/*
==============================
F: -5 I:11
F: -10 I:22
==============================
*/