运算符重载使得用户自定义的数据以一种更简洁的方式工作。
重载运算符函数可以对运算符作出新的解释,但原有基本语义不变:
不改变运算符的优先级。
不改变运算符的结合性。
不改变运算符所需要的操作数。
不能创建新的运算符。
运算符重载的语法形式
运算符重载是一种特殊的成员函数或友元函数。
成员函数的语法形式为:
类型 类名::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;//用构造函数进行转换
小结
运算符重载可以像基本数据类型一样,用间接明确的运算符操作自定义的类对象。
重载运算符函数可以对运算符作出新的解释,但原有的基本语义不变。
运算符重载既可以重载为成员函数,也可以重载为友元函数或普通函数。
当一元运算符的操作数,或者二元运算符的左操作数是类的一个对象时,以成员函数重载;当一个运算符的操作需要改变对象状态时,应该以成员函数重载。如果以友元函数重载,则使用引用参数修改对象。
当运算符的操作数(尤其是第一个操作数)希望有隐式转换,则重载运算符时必须使用友元函数。
构造函数和类型转换函数可以实现基本类型与类类型,以及类类型之间的类型转换。