重载意义
函数重载(Function Overloading)可以让一个函数名有多种功能,在不同情况下进行不同的操作;
运算符重载(Operator Overloading)也是一个道理,同一个运算符可以有不同的功能;C++中预定义的运算符的操作对象只能是基本数据类型。但实际上,对于许多用户自定义类型(例如类),也需要类似的运算操作。这时就必须在C++中重新定义这些运算符,赋予已有运算符新的功能,使它能够用于特定类型执行特定的操作。运算符重载的实质是函数重载,它提供了C++的可扩展性,也是C++最吸引人的特性之一。
比如,我们定义两个string类对象a,b后我们之所以可以使用+运算,是因为string类重载了+运算符。
语法
1
2
3
4<返回类型说明符> operator <运算符符号>(<参数表>)
{
<函数体>
}哪些运算符可以被重载,哪些运算符不能被重载
可以被重载的运算符:
算术运算符:
+ , - , * , / , % , ++ , --
位操作运算符:& , | , ~ , ^ , << , >>
逻辑运算符:! , && , ||
比较运算符:< , > , >= , <= , == , !=
赋值运算符:= , += , -= , *= , /= , %= , &= , |= , ^= , <<= , >>=
其他运算符:[] , () , -> , ,(逗号运算符) , new , delete , new[] , delete[] , ->*
不允许的运算符重载:
. , .* , :: , ?: ,siezof
Notes:
运算符重载函数是类的成员函数时
>- 注意
要是内部的,必须得是
<=1
个参数,不需要加friend
(友元函数) - 语法(在类内声明,在类外实现时的代码)
1
2
3
4
5<返回类型说明符> <类名>::operator <运算符符号>(<参数表>)
{
<函数体>
}
- 注意
运算符重载函数不是类的成员函数时
(或者说当运算符函数是非成员函数时
)- 函数在类中声明的时候需要在前面加上
friend
(友元函数),不管参数是不是类的对象 - 函数的参数与该运算符作用的运算对象数量一样多
- 函数在类中声明的时候需要在前面加上
为什么用
const
和&
:const
:- 我们不希望在这个函数中对用来进行赋值的“原版”做任何修改。函数加上const后缀的作用是表明函数本身不会修改类成员变量。
- 加上const,对于const的和非const的实参,函数就能接受;如果不加,就只能接受非const的实参。
&
(引用):这样可以避免在函数调用时对实参的一次拷贝,提高了效率。
代码
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/**
* Author: Dgimo
* Date: 2020/3/30
* TODO: 类运算符重载
* Describe:
*/
using namespace std;
typedef struct {
int first;
int second;
} TestStuct;
/*
* 类运算符重载
*/
class TestClass {
private:
int first;
int second;
public:
TestClass(int, int);
TestClass();
void show(string);
TestClass operator+(const TestClass &);
TestClass operator+(const TestStuct &);
friend TestClass operator+(const TestClass &, const TestClass &); // 如果不是内部的,得加friend 声明不是内部的,如果不是两个会怎样?见下面!!!
friend TestClass operator+(const TestStuct &, const TestStuct &); // 只要在类内部定义的运算符重载,就需要加上friend
// TestClass operator+(const TestClass &, const TestClass &); // 要是内部的,必须得是<=1个参数,不需要加 friend
};
TestClass::TestClass(int first, int second) {
this->first = first;
this->second = second;
}
TestClass::TestClass()
{
this->first = 1;
this->second = 2;
}
TestClass TestClass::operator+(const TestClass &tc) { // TestClass + TestClass
return TestClass(first + tc.first, second + tc.second);
}
TestClass TestClass::operator+(const TestStuct & ts) { // TestClass + TestStruct
return TestClass(first + ts.first, second + ts.second);
}
TestClass operator+(const TestClass &fir, const TestClass &sec) { // 全局:TestClass + TestCLass 实际上和 TestClass TestClass::operator+(const TestClass &tc)
return TestClass(fir.first + sec.first, fir.second + sec.second);
}
TestClass operator+(const TestStuct &fir, const TestStuct &sec) {
return TestClass(fir.first + sec.first, fir.second + sec.second);
}
void TestClass::show(string str) {
cout << str << ": " << "first: " << this->first << ", second: " << this->second << endl;
}
int main()
{
TestClass tc1, add_tc, add_tc1, add_ts;
TestClass tc2 = TestClass(2, 3);
TestStuct ts1, ts2;
ts1.first = 1, ts1.second = 2;
ts2.first = 10, ts2.second = 20;
tc1.show("tc1");
tc2.show("tc2");
add_tc = tc1 + tc2; // TestClass + TestClass
add_tc.show("add_tc");
add_tc1 = add_tc + ts1; // TestClass + TestStruct
add_tc1.show("add_tc1");
add_ts = ts1 + ts2; // TestStrcut + TestStrcut
add_ts.show("add_ts");
return 0;
}
暂时未发现
Bug
代码
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/**
* Author: Dgimo
* Date: 2020/3/31
* TODO: 结构体运算符重载
* Describe:
*/
using namespace std;
/*
* 结构体运算符重载
*/
typedef struct {
int first;
int second;
} TestStuct;
TestStuct operator+(TestStuct ts1, TestStuct ts2)
{
TestStuct res;
res.first = ts1.first + ts2.first;
res.second = ts1.second + ts2.second;
return res;
}
bool show(TestStuct ts)
{
cout << "first: " << ts.first << ", second: " << ts.second << endl;
}
int main()
{
TestStuct ts1;
ts1.first = 1;
ts1.second = 2;
TestStuct ts2;
ts2.first = 2;
ts2.second = 3;
TestStuct res_t = ts1 + ts2;
show(res_t);
return 0;
}
原因
定义为成员函数,那么就隐含this指针了对吧,你要知道重载其实也是一种函数,那么函数就有调用他的对象,如果是成员函数,那么调用他的对象就肯定是想对应的类对象了对吧,但是<<和>>调用的对象肯定只能是cout或者cin对吧,那么久不能定义为成员函数了,只有定义成友元,那么就可以把cin,cout作为一个参数传进你重载的操作符函数里面去了
语法:
在类中:
1
friend ostream &operator <<(ostream &out, const ElemType &e);
在外面:
1
ostream &oprator <<(ostream &out, const ElemType &e);
代码
头文件(
.h
)1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
using namespace std;
class ElemType
{
public:
int data;
ElemType();
ElemType(int);
friend ostream &operator <<(ostream &out, const ElemType &e); // Success
protected:
private:
};源文件(
.cpp
)1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
ElemType::ElemType()
{
//ctor
this->data = 0;
}
ElemType::ElemType(int data)
{
this->data = data;
}
ostream& operator <<(ostream &out, const ElemType &e)
{
out << e.data;
return out;
}