C++-操作符重载、并实现复数类详解

首先回忆下以前学的函数重载

函数重载

  1. 函数重载的本质为相互独立的不同函数
  2. 通过函数名和函数参数来确定函数调用
  3. 无法直接通过函数名得到重载函数的入口地址
  4. 函数重载必然发生在同一个作用域中

类中的函数重载

  1. 静态成员函数能与普通成员函数建立重载关系
  2. 全局函数和成员函数不能构成重载关系

操作符重载(operator)

什么是操作符重载?

大家都知道,在C里,有'+,-,*,/'这些操作符,且它们的功能就是实现普通变量运算。

由于C++是面向对象的,遇到的变量大多都是对象,所以优化了C里的操作符,使它们拥有了重载能力.能通过一定方式,使对象能进行'+,-,*,/'等运算.

操作符的重载是以函数的方式进行.

操作符重载定义

操作符重载,通过operator关键字在函数前定义:

?

1

2

3

4

5

6

7

[返回类型] operator [需要重载的操作符](函数参数)

  

{

  

    //......

  

}

作符重载有几种方式 : 全局操作符重载函数、全局操作符重载函数

编译器首先会判断运算的若是对象,就会先从类里寻找成员操作符重载函数,若没找到,就会再去全局里寻找全局操作符重载函数.

注意事项:

  1. 操作符重载不能改变原操作符的优先级
  2. 操作符重载不能改变操作数的个数
  3. 操作符重载的参数一般设为const class_name &类型(若只设为const class_name,会产生临时对象)
  4. 在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的算术平方根

所以复数类的操作符重载共有以下几个:

C++-操作符重载、并实现复数类详解

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                                   //为假