首先回忆下以前学的函数重载
函数重载
- 函数重载的本质为相互独立的不同函数
- 通过函数名和函数参数来确定函数调用
- 无法直接通过函数名得到重载函数的入口地址
- 函数重载必然发生在同一个作用域中
类中的函数重载
- 静态成员函数能与普通成员函数建立重载关系
- 全局函数和成员函数不能构成重载关系
操作符重载(operator)
什么是操作符重载?
大家都知道,在C里,有'+,-,*,/'这些操作符,且它们的功能就是实现普通变量运算。
由于C++是面向对象的,遇到的变量大多都是对象,所以优化了C里的操作符,使它们拥有了重载能力.能通过一定方式,使对象能进行'+,-,*,/'等运算.
操作符的重载是以函数的方式进行.
操作符重载定义
操作符重载,通过operator关键字在函数前定义:
1
2
3
4
5
6
7
|
[返回类型] operator [需要重载的操作符](函数参数)
{
//......
}
|
作符重载有几种方式 : 全局操作符重载函数、全局操作符重载函数
编译器首先会判断运算的若是对象,就会先从类里寻找成员操作符重载函数,若没找到,就会再去全局里寻找全局操作符重载函数.
注意事项:
- 操作符重载不能改变原操作符的优先级
- 操作符重载不能改变操作数的个数
- 操作符重载的参数一般设为const class_name &类型(若只设为const class_name,会产生临时对象)
- 在C++中,有些操作符必须需要有对象支持,所以只能为成员函数.这种被称为一元操作符
比如赋值(=)、下标([])、下标([])、调用(())和成员访问箭头(->):
1
|
Test t3=t2; //相当于调用了: Test t3.operator =(t2); 里面会通过this指针来代替左侧数t3
|
有些操作符既可以当做成员操作符重载函数,也可以当做全局操作符重载函数,由于函数参数可以多个,便称为二元操作符
比如加法(+),与(&&),或(||),逗号(,)等:
以加法(+)为例,当设为全局操作符重载函数时,执行
1
|
Test t3=t1+t2; //相当于调用了: Test t3 = operator +(t1,t2);
|
以加法(+)为例,当设为成员操作符重载函数时,执行
1
|
Test t3=t1+t2; //相当于调用了: Test t3 =t1.operator +(t2); //里面会通过this指针来代替左侧数t1
|
多个重载的操作符重载函数
由于操作符重载函数带参数,所以可以存在多个相同的操作符重载函数
例如:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
class Test
{
double x;
double y;
public :
Test operator +( const Test& t); //实现Test t3=t1+t2
Test operator +( int i); //实现Test t3=t1+1
Test operator +( double d); //实现Test t3=t1+1.25
//... ...
};
|
初步试验
1.接下来,来个全局操作符重载函数例子:
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
|
#include "stdio.h"
class Test{
int x;
int y;
public :
Test( int x=0, int y=0)
{
this ->x=x;
this ->y=y;
}
int getx()
{
return x;
}
int gety()
{
return y;
}
friend Test operator + ( const Test& t1, const Test& t2);
//声明友元函数,可以使用私有成员变量
};
Test operator + ( const Test& t1, const Test& t2) //重载
{
Test ret;
ret.x=t1.x+t2.x;
ret.y=t1.y+t2.y;
return ret;
}
int main()
{
Test t1(1,3);
Test t2(2,4);
Test t3= t1 + t2; // 其实就是调用: Test t3 = operator +(t1,t2);
printf ( "t3.x:%d t3.y:%d\n" ,t3.getx(),t3.gety());
Test t4 =operator +(t1,t3); // t4 =t1 +t3
printf ( "t4.x:%d t4.y:%d\n" ,t4.getx(),t4.gety());
return 0;
}
|
打印结果:
t3.x:3 t3.y:7
t4.x:4 t4.y: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
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
|
#include "stdio.h"
class Test{
int x;
int y;
public :
Test( int x=0, int y=0)
{
this ->x =x;
this ->y =y;
}
int getx()
{
return x;
}
int gety()
{
return y;
}
Test operator + ( const Test& t2)
{
Test ret;
ret.x = this ->x + t2.x;
ret.y = this ->y + t2.y;
return ret;
}
};
int main()
{
Test t1(1,3);
Test t2(2,4);
Test t3= t1 + t2; // 其实就是调用: Test t3 =t1.operator +(t2);
printf ( "t3.x:%d t3.y:%d\n" ,t3.getx(),t3.gety());
Test t4 =t1.operator +(t3); // t4 =t1 +t3
printf ( "t4.x:%d t4.y:%d\n" ,t4.getx(),t4.gety());
return 0;
}
|
打印结果:
t3.x:3 t3.y:7
t4.x:4 t4.y:10
加深理解
由于C++里,没有复数的慨念,而在刚刚又学习了操作符重载,所以接下来便通过操作符重载来实现复数类
复数类应该具有
两个成员
实部a 、虚部b
运算操作符
+ - : 结果 = 两个实部进行加减,两个虚部进行加减
* : 结果 = (a1+b1)(a2+b2)= (a1*a2 - b1*b2 )+( a2*b1 + a1*b2);
/ : 结果 =(a1+b1)/(a2+b2)= (a1*a2+b1*b2)/(a2* a2+b2* b2) +(b1*a2-a1*b2)/(a2* a2+b2* b2)
比较操作符:== ,!=
赋值操作符: =
求模成员函数 : 等于a^2+b^2的算术平方根
所以复数类的操作符重载共有以下几个:
1.写头文件Complex.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
|
#ifndef __COMPLEX_H
#define __COMPLEX_H
class Complex{
private :
double a;
double b;
public :
Complex( int a=0, int b=0);
Complex operator + ( const Complex& t);
Complex operator - ( const Complex& t);
Complex operator * ( const Complex& t);
Complex operator / ( const Complex& t);
bool operator == ( const Complex& t);
bool operator != ( const Complex& t);
Complex& operator = ( const Complex& t);
double getModulus();
double getA();
double getB();
};
#endif
|
2.写源文件Complex.cpp
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
|
#include "Complex.h"
#include "math.h"
Complex::Complex( int a, int b)
{
this ->a = a;
this ->b = b;
}
Complex Complex::operator + ( const Complex& t)
{
Complex ret;
ret.a = a + t.a;
ret.b = b + t.b;
return ret;
}
Complex Complex::operator - ( const Complex& t)
{
Complex ret;
ret.a = a - t.a;
ret.b = b - t.b;
return ret;
}
Complex Complex::operator * ( const Complex& t)
{
Complex ret;
ret.a = (a* t.a - b* t.b );
ret.b = (t.a *b + a* t.b );
return ret;
}
Complex Complex::operator / ( const Complex& t)
{
Complex ret;
ret.a = (a* t.a + b* t.b)/(t.a * t.a + t.b * t.b);
ret.b = (b* t.a - a* t.b)/(t.a * t.a + t.b * t.b);
return ret;
}
bool Complex::operator == ( const Complex& t)
{
if ((a== t.a)&&(b== t.b))
return true ;
else
return false ;
}
bool Complex::operator != ( const Complex& t)
{
if ((a!= t.a)||(b!= t.b))
return true ;
else
return false ;
}
Complex& Complex::operator = ( const Complex& t)
{
if ( this != &t)
{
a = t.a;
b = t.b;
}
return * this ;
}
double Complex::getModulus()
{
return sqrt ( a*a + b*b);
}
double Complex::getA()
{
return a;
}
double Complex::getB()
{
return b;
}
|
3.写测试文件test.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
#include "stdio.h"
#include "Complex.h"
int main()
{
Complex t1(1,3);
Complex t2(2,6);
Complex t3=t1+t2;
printf ( "t3.a=%f t3.b=%f\n" ,t3.getA(),t3.getB());
printf ( "t3 Modulus:%f\n" ,t3.getModulus());
Complex t4=t3;
printf ( "t4==t3: %d\n" ,t4==t3);
printf ( "t4!=t3: %d\n" ,t4!=t3);
printf ( "t3==t1: %d\n" ,t3==t1);
return 0;
}
|
4.编译运行
t3.a=3.000000 t3.b=9.000000
t3 Modulus:9.486833
t4==t3: 1 //为真
t4!=t3: 0 //为假
t3==t1: 0 //为假
以上所述是小编给大家介绍的C++-操作符重载、并实现复数类详解详解整合,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对服务器之家网站的支持!
原文链接:https://www.cnblogs.com/lifexy/p/8635556.html