运算符重载

运算符重载概述

C++ 允许在同一作用域中的某个函数运算符指定多个定义,分别称为函数重载运算符重载

重载声明是指一个与之前已经在该作用域内声明过的函数或方法具有相同名称的声明,但是它们的参数列表和定义(实现)不相同。

当您调用一个重载函数重载运算符时,编译器通过把您所使用的参数类型与定义中的参数类型进行比较,决定选用最合适的定义。选择最合适的重载函数或重载运算符的过程,称为重载决策

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

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

分类 解释
双目算术运算符 +-*/%
关系运算符 ==!=<><=>=
逻辑运算符 \|\|&&!
单目运算符 +-*&
自增自减运算符 ++--
位运算符 \|&~^<<>>
赋值运算符 =+=-=*=/=%=&=\|=^=<<=>>=
空间申请与释放 newdeletenew[]delete[]
其他运算符 ()->,[]

C++ 智能指针 -> 运算符。

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

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

重载运算符的一些规则和建议

  1. 对于 +-*/% 这些双目算术运算符和 ==!=<><=>= 这些关系运算符来说,既可以使用成员函数的方式重载,也可以使用非成员函数的方式重载,如果是两个相同类型的相加,如一个 Person 类型的数据和另外一个 Person 类型的数据相加,则哪种方式都可以;但如果是一个 int 类型的数据和 Person 类型的数据相加,则要使用非成员函数的方式重载。建议:非成员函数的方式重载。
  2. 对于 +- 这两个单目运算符来说,既可以通过成员函数的方式重载,也可以使用非成员函数的方式重载。建议:非成员函数的方式重载。
  3. 对于 ++-- 这两个运算符来说,必须通过成员函数的方式重载,对于后置的操作符要有一个占位参数。
  4. 对于 <<>> 这两个流操作运算符来说,必须通过非成员函数的方式重载。
  5. 对于 =+=-=*=/=%=&=|=^=<<=>>= 这些赋值运算符来说,必须通过非成员函数的方式重载。
  6. ()[]-> 必须通过成员函数重载。
  7. 不要重载 ||&&!&.

运算符重载的一些例子

vec2

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
49
50
51
52
53
54
55
56
/**
* @file : vec2.h
* @date : 2023/06/21 12:11:34
* @author : yaojie
* @version : 1.0
*/

#ifndef VEC2_H
#define VEC2_H

#include <iostream>

class Vec2 {
public:
Vec2();
Vec2(double x, double y);
Vec2(const Vec2 &v);
~Vec2();

public:
double length();

public:
Vec2 &operator=(const Vec2 &v);
Vec2 &operator+=(const Vec2 &v);
Vec2 &operator-=(const Vec2 &v);
Vec2 &operator*=(const Vec2 &v);
Vec2 &operator/=(const Vec2 &v);

Vec2 &operator+();
Vec2 operator-();
Vec2 &operator++();
Vec2 operator++(int);
Vec2 &operator--();
Vec2 operator--(int);

int operator[](std::size_t idx);
const int operator[](std::size_t idx) const;

friend Vec2 operator+(const Vec2 &v1, const Vec2 &v2);
friend Vec2 operator-(const Vec2 &v1, const Vec2 &v2);
friend Vec2 operator*(const Vec2 &v1, const Vec2 &v2);
friend Vec2 operator/(const Vec2 &v1, const Vec2 &v2);

friend bool operator==(const Vec2 &v1, const Vec2 &v2);
friend bool operator!=(const Vec2 &v1, const Vec2 &v2);

friend std::ostream &operator<<(std::ostream &os, const Vec2 &v);
friend std::istream &operator>>(std::istream &is, Vec2 &v);

private:
double x;
double y;
};

#endif
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
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
/**
* @file : vec2.cpp
* @date : 2023/06/21 12:29:10
* @author : yaojie
* @version : 1.0
*/

#include "vec2.h"
#include <cmath>

Vec2::Vec2() : x(0), y(0) {}

Vec2::Vec2(double x, double y) : x(x), y(y) {}

Vec2::Vec2(const Vec2 &v) {
x = v.x;
y = v.y;
}

Vec2::~Vec2() {}

double Vec2::length() const { return fsqrt(x * x + y * y); }

Vec2 &Vec2::operator=(const Vec2 &v) {
x = v.x;
y = v.y;
return *this;
}

Vec2 &Vec2::operator+=(const Vec2 &v) {
x += v.x;
y += v.y;
return *this;
}

Vec2 &Vec2::operator-=(const Vec2 &v) {
x -= v.x;
y -= v.y;
return *this;
}

Vec2 &Vec2::operator*=(const Vec2 &v) {
x *= v.x;
y *= v.y;
return *this;
}

Vec2 &Vec2::operator/=(const Vec2 &v) {
x /= v.x;
y /= v.y;
return *this;
}

Vec2 &Vec2::operator+() { return *this; }

Vec2 Vec2::operator-() const { return Vec2{-x, -y}; }

Vec2 &Vec2::operator++() {
x = x + 1;
y = y + 1;
return *this;
}

Vec2 Vec2::operator++(int) {
Vec2 tmp{x, y};
x = x + 1;
y = y + 1;
return tmp;
}

Vec2 &Vec2::operator--() {
x = x - 1;
y = y - 1;
return *this;
}

Vec2 Vec2::operator--(int) {
Vec2 tmp{x, y};
x = x - 1;
y = y - 1;
return tmp;
}

Vec2 operator+(const Vec2 &v1, const Vec2 &v2) {
return {v1.x + v2.x, v2.x + v2.y};
}

Vec2 operator-(const Vec2 &v1, const Vec2 &v2) {
return {v1.x - v2.x, v2.x - v2.y};
}

Vec2 operator*(const Vec2 &v1, const Vec2 &v2) {
return {v1.x * v2.x, v2.x * v2.y};
}

Vec2 operator/(const Vec2 &v1, const Vec2 &v2) {
return {v1.x / v2.x, v2.x / v2.y};
}

bool operator==(const Vec2 &v1, const Vec2 &v2) {
return fabs(v1.x - v2.x) < 0.01 && fabs(v1.y - v2.y) < 0.01;
}

bool operator!=(const Vec2 &v1, const Vec2 &v2) { return !(v1 == v2); }

std::ostream &operator<<(std::ostream &os, const Vec2 &v) {
return os << v.x << ' ' << v.y;
}

std::istream &operator>>(std::istream &is, Vec2 &v) {
is >> v.x >> v.y;
return is;
}

int Vec2::operator[](std::size_t idx) {
if (idx == 0) {
return x;
}
if (idx == 1) {
return y;
}
throw "下标越界";
}

const int Vec2::operator[](std::size_t idx) const {
if (idx == 0) {
return x;
}
if (idx == 1) {
return y;
}
throw "下标越界";
}

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
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
/**
* @FileName : Int.h
* @Author : yaojie
* @Date : 2023/6/25
*/

#ifndef INT_H
#define INT_H

#include <iostream>

class Int {
public:
Int();

Int(int val);

Int(const Int &i);

~Int();

public:
Int &operator+();
Int operator-();

Int &operator++();
Int operator++(int);
Int &operator--();
Int operator--(int);

Int &operator=(const Int &i);
Int &operator+=(const Int &i);
Int &operator-=(const Int &i);
Int &operator*=(const Int &i);
Int &operator/=(const Int &i);
Int &operator%=(const Int &i);

friend Int operator+(const Int &a, const Int &b);
friend Int operator-(const Int &a, const Int &b);
friend Int operator*(const Int &a, const Int &b);
friend Int operator/(const Int &a, const Int &b);
friend Int operator%(const Int &a, const Int &b);

friend bool operator==(const Int &a, const Int &b);
friend bool operator!=(const Int &a, const Int &b);
friend bool operator>(const Int &a, const Int &b);
friend bool operator<(const Int &a, const Int &b);
friend bool operator>=(const Int &a, const Int &b);
friend bool operator<=(const Int &a, const Int &b);

friend std::ostream &operator<<(std::ostream &os, const Int i);
friend std::istream &operator>>(std::istream &is, Int i);

private:
int val;
};

#endif // INT_H

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
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
/**
* @FileName : Int.cpp
* @Author : yaojie
* @Date : 2023/6/25
*/

#include "Int.h"

Int::Int() : Int(0) {}

Int::Int(int val) : val(val) {}

Int::Int(const Int &i) { this->val = i.val; }

Int::~Int() {}

Int &Int::operator+() { return *this; }

Int Int::operator-() { return {-this->val}; }

Int &Int::operator++() {
++this->val;
return *this;
}

Int Int::operator++(int) {
Int tmp{this->val};
this->val++;
return tmp;
}

Int &Int::operator--() {
--this->val;
return *this;
}

Int Int::operator--(int) {
Int tmp{this->val};
this->val--;
return tmp;
}

Int &Int::operator=(const Int &i) {
this->val = i.val;
return *this;
}

Int &Int::operator+=(const Int &i) {
this->val += i.val;
return *this;
}

Int &Int::operator-=(const Int &i) {
this->val -= i.val;
return *this;
}

Int &Int::operator*=(const Int &i) {
this->val *= i.val;
return *this;
}

Int &Int::operator/=(const Int &i) {
this->val /= i.val;
return *this;
}

Int &Int::operator%=(const Int &i) {
this->val %= i.val;
return *this;
}

Int operator+(const Int &a, const Int &b) { return {a.val + b.val}; }
Int operator-(const Int &a, const Int &b) { return {a.val - b.val}; }
Int operator*(const Int &a, const Int &b) { return {a.val * b.val}; }
Int operator/(const Int &a, const Int &b) { return {a.val / b.val}; }
Int operator%(const Int &a, const Int &b) { return {a.val % b.val}; }

bool operator==(const Int &a, const Int &b) { return a.val == b.val; }
bool operator!=(const Int &a, const Int &b) { return a.val != b.val; }
bool operator>(const Int &a, const Int &b) { return a.val > b.val; }
bool operator<(const Int &a, const Int &b) { return a.val < b.val; }
bool operator>=(const Int &a, const Int &b) { return a.val >= b.val; }
bool operator<=(const Int &a, const Int &b) { return a.val <= b.val; }

std::ostream &operator<<(std::ostream &os, const Int i) { return os << i.val; }
std::istream &operator>>(std::istream &is, Int i) { return is >> i.val; }

参考