9.1运算符重载

运算符重载使得用户自定义的数据以一种更简洁的方式工作。

重载运算符函数可以对运算符作出新的解释,但原有基本语义不变:

不改变运算符的优先级。

不改变运算符的结合性。

不改变运算符所需要的操作数。

不能创建新的运算符。

运算符重载的语法形式

运算符重载是一种特殊的成员函数或友元函数。

成员函数的语法形式为:

类型 类名::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类型转换函数

6.4.1构造函数进行类类型转换

数据类型转换在程序编译时或在程序运行实现:

基本类型<-->基本类型

基本类型<-->类类型

类类型<-->类类型

类对象的类型转换可由两种方式说明:

构造函数 转换函数

称为用户定义的类型转换或类类型转换,有隐式调用和现式调用方式。

隐式调用和现式调用

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 }

6.4.2类型转换函数

带参数的构造函数不能把一个类类型转换成基本类型。

类类型转换函数是一种特殊的成员函数,提供类对象之间显式类型转换的机制。

(实质上通过重载完成) 

语法形式:

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;//用构造函数进行转换

小结

运算符重载可以像基本数据类型一样,用间接明确的运算符操作自定义的类对象。

重载运算符函数可以对运算符作出新的解释,但原有的基本语义不变。

运算符重载既可以重载为成员函数,也可以重载为友元函数或普通函数。

当一元运算符的操作数,或者二元运算符的左操作数是类的一个对象时,以成员函数重载;当一个运算符的操作需要改变对象状态时,应该以成员函数重载。如果以友元函数重载,则使用引用参数修改对象。

当运算符的操作数(尤其是第一个操作数)希望有隐式转换,则重载运算符时必须使用友元函数。

构造函数和类型转换函数可以实现基本类型与类类型,以及类类型之间的类型转换。

原文地址:https://www.cnblogs.com/denggelin/p/5665172.html