运算符重载使得用户自定义的数据以一种更简洁的方式工作。
重载运算符函数可以对运算符作出新的解释,但原有基本语义不变:
不改变运算符的优先级。
不改变运算符的结合性。
不改变运算符所需要的操作数。
不能创建新的运算符。
运算符重载的语法形式
运算符重载是一种特殊的成员函数或友元函数。
成员函数的语法形式为:
类型 类名::operator op(参数表)
{
//相对于该类定义的操作
}
//友元函数可以处理不同类型
//类运算符可以实现的,友元函数大部分都可以实现
//友元函数更强大
//=、()、[]、->这个4个运算符只能用类运算符来重载
复数重载运算符
重载<<
重载>>
重载前缀++
重载前缀--
重载()
1 #include <iostream>
2
3 //友元函数可以处理不同类型
4 //类运算符可以实现的,友元函数大部分都可以实现
5 //友元函数更强大
6 //=、()、[]、->这个4个运算符只能用类运算符来重载
7
8 class mycomplex
9 {
10 public:
11 int x;
12 int y;//xy坐标
13 mycomplex()//构造函数
14 {
15 this->x = 0;
16 this->y = 0;
17 }
18 mycomplex(int x, int y)//构造函数
19 {
20 this->x = x;
21 this->y = y;
22 }
23 void operator ++();//重载前缀++
24 void operator --();//重载前缀--
25 int operator ()(int num);//重载()
26 mycomplex operator +(mycomplex adddata);//重载+
27
28 //ostream是标准输出流
29 friend std::ostream &operator<<(std::ostream &, mycomplex &);//声明友元函数,重载<<
30 //istream是标准输入流
31 friend std::istream &operator>>(std::istream &, mycomplex &);//声明友元函数,重载>>
32 friend mycomplex operator+(mycomplex adddata1, mycomplex adddata2);//重载+
33 };
34
35 void mycomplex::operator ++()//重载前缀++
36 {
37 this->x++;
38 this->y++;
39 }
40
41 void mycomplex::operator --()//重载前缀--
42 {
43 this->x--;
44 this->y--;
45 }
46
47 int mycomplex::operator ()(int num)//重载()
48 {
49 std::cout << num << std::endl;
50 return num + num;
51 }
52
53 mycomplex mycomplex::operator +(mycomplex adddata)
54 {
55 mycomplex temp;
56 temp.x = this->x + adddata.x;
57 temp.y = this->y + adddata.y;
58 return temp;
59 }
60
61 std::ostream &operator<<(std::ostream & out, mycomplex & Complex)//定义友元函数,重载<<
62 {
63 std::cout << Complex.x << "+" << Complex.y << "i" << std::endl;
64 return out;
65 }
66
67 std::istream &operator>>(std::istream & in, mycomplex & Complex)//定义友元函数,重载>>
68 {
69 std::cout << "请输入xy" << std::endl;
70 in >> Complex.x;
71 in >> Complex.y;
72 return in;
73 }
74
75 mycomplex operator+(mycomplex adddata1, mycomplex adddata2)//重载+
76 {
77 mycomplex temp;
78 temp.x = adddata1.x + adddata2.x;
79 temp.y = adddata1.y + adddata2.y;
80 return temp;
81 }
82
83 void main()
84 {
85 mycomplex my1(7, 8), my2(9, 10);
86
87 std::cout << my1;//重载<<
88 std::cout << my2;//重载<<
89
90 mycomplex my3;
91
92 std::cin >> my3;//重载>>
93
94 ++my3;//重载前缀++
95 --my3;//重载前缀--
96
97 std::cout << my3;//重载<<
98
99 std::cout << my3(1) << std::endl;//重载()
100
101 std::cout << my1 + my2 << std::endl;
102
103 system("pause");
104 }
输出<<输入>>和外部有关系,因此使用友元函数重载运算符
自增++自减--括号()和外部没有关系,因此使用类运算符重载
用成员或友元函数重载运算符
运算符函数可以重载为成员函数或友元函数。
关键区别在于成员函数具有this指针,友元函数没有this指针。
不管是成员函数函数还是友元函数重载,运算符的使用方法相同。
但传递参数的方式不同,实现代码不同,应用场合也不同。
重载赋值运算符
赋值运算符重载用于对象数据的复制。
operator=必须重载为成员函数
重载函数原型为:
类型 & 类名::operator=(const 类名&);
6.4类的类型转换
6.4.1构造函数进行类类型转换
6.4.2类型转换函数
数据类型转换在程序编译时或在程序运行实现:
基本类型<-->基本类型
基本类型<-->类类型
类类型<-->类类型
类对象的类型转换可由两种方式说明:
构造函数 转换函数
称为用户定义的类型转换或类类型转换,有隐式调用和现式调用方式。
隐式调用和现式调用
1 void main()
2 {
3 int num1 = (int)10.8;//显式转换
4 int num2 = 10.8;//隐式转换
5 std::cout << num1 << " " << num2 << std::endl;
6
7 system("pause");
8 }
//error C2440: “初始化”: 无法从“void *”转换为“int *”
//C风格类型转换
1 #include <iostream>
2 using namespace std;
3
4 void main()
5 {
6 void *p = new int[10];
7
8 //int *pint = p;//error C2440: “初始化”: 无法从“void *”转换为“int *”
9
10 int *pint = (int *)p;//C风格类型转换
11
12 system("pause");
13 }
带参数的构造函数不能把一个类类型转换成基本类型。
类类型转换函数是一种特殊的成员函数,提供类对象之间显式类型转换的机制。
(实质上通过重载完成)
语法形式:
X::operator T()
......
return T类型的对象
功能:将类型X的对象转换为类型T的对象
T可以预定义类型,也可以是用户定义类型。
函数没有参数,没有返回类型,但必须有一条return语句,返回T类型的对象。
该函数只能为成员函数,不能为友元。
//类类之间的转换函数
1 #include <iostream>
2
3 class fushu
4 {
5 public:
6 explicit fushu(int num)
7 {
8 x = num;
9 y = num;
10 }
11 void print()
12 {
13 std::cout << x << " " << y << std::endl;
14 }
15 operator int();//类类之间的转换函数
16 private:
17 int x;
18 int y;
19 };
20
21 fushu::operator int()//类类之间的转换函数
22 {
23 return x + y;
24 }
25
26 void main()
27 {
28 int num(10.9);
29 fushu fushu1(num);
30
31 int data = fushu1;
32
33 std::cout << data << std::endl;//20
34
35 system("pause");
36 }
类型转换函数有两种使用方式:
隐式使用 i=a;
显式使用 i=a.operator int();//int(a);(int)a
使用不同函数作类型转换函数:
int i=a;//用类型转换函数进行转换
X i=a;//用构造函数进行转换
小结
运算符重载可以像基本数据类型一样,用间接明确的运算符操作自定义的类对象。
重载运算符函数可以对运算符作出新的解释,但原有的基本语义不变。
运算符重载既可以重载为成员函数,也可以重载为友元函数或普通函数。
当一元运算符的操作数,或者二元运算符的左操作数是类的一个对象时,以成员函数重载;当一个运算符的操作需要改变对象状态时,应该以成员函数重载。如果以友元函数重载,则使用引用参数修改对象。