1,下面的复数解决方案是否可行?
1,代码示例:
1 class Comples 2 { 3 public: 4 int a; 5 int b; 6 }; 7 8 int main() 9 { 10 Complex c1 = {1, 2}; 11 Complex c2 = {3, 4}; 12 Complex c3 = c1 + c2; // error: no match for 'operator' in 'c1 + c2' 13 14 return 0; 15 }
2,重载最深层次的意义在于通过重载可以扩展系统已有的功能;
3,成员变量为公有且没有自定义构造函数的时候,可以通过大括号来分别初始 化成员变量;
2,复数的加法操作编程实验:
1,main.cpp 文件:
1 #include <stdio.h> 2 3 class Complex 4 { 5 int a; 6 int b; 7 public: 8 Complex(int a = 0, int b = 0) 9 { 10 this->a = a; 11 this->b = b; 12 } 13 14 int getA() 15 { 16 return a; 17 } 18 19 int getB() 20 { 21 return b; 22 } 23 24 friend Complex Add(const Complex& p1, const Complex& p2); 25 }; 26 27 Complex Add(const Complex& p1, const Complex& p2) 28 { 29 Complex ret; 30 31 ret.a = p1.a + p2.a; 32 ret.b = p1.b + p2.b; 33 34 return ret; 35 } 36 37 int main() 38 { 39 40 Complex c1(1, 2); 41 Complex c2(3, 4); 42 Complex c3 = Add(c1, c2); // c1 + c2 43 44 printf("c3.a = %d, c3.b = %d ", c3.getA(), c3.getB()); 45 46 return 0; 47 }
2,输出结果:
c3.a = 4, c3.b = 6
3,思考:
1,Add 函数可以解决 Complex 对象相加的问题,但是 Complex 是现实世界中确切存在的复数,并且复数在数学中的地位和普通的实数相同;
2,为什么不能让 + 操作符也支持复数相加呢?
1,因为复数是我们自定义的类,编译器不知道这个类;
2,C++ 中扩展已有的功能可以通过重载来实现;
4,操作符重载:
1,C++ 中的重载能够扩展操作符的功能;
2,操作符的重载以函数的方式进行;
3,本质:
1,用特殊形式的函数扩展操作符的功能;
4,通过 operator 关键字可以定义特殊形式的函数;
5,operator 的本质是通过函数重载操作符;
6,语法:
1,代码示例:
1 Type operator Sign(const Type& p1, const Type& p2) // operator 关键字作为特殊形式函数的前缀,它直接告诉编译器,如果有两个 Type 对象做 Sign 运算,则直接调用本函数; 2 { 3 Type ret; 4 5 return ret; 6 }
2,Sign 为系统中预定义的操作符,如:+,-,*,/等;
3,仅在定义时函数名特殊,调用时和普通函数相同;
5,操作符重载初探编程实验:
1,main.cpp 文件:
1 #include <stdio.h> 2 3 class Complex 4 { 5 int a; 6 int b; 7 public: 8 Complex(int a = 0, int b = 0) 9 { 10 this->a = a; 11 this->b = b; 12 } 13 14 int getA() 15 { 16 return a; 17 } 18 19 int getB() 20 { 21 return b; 22 } 23 24 friend Complex operator + (const Complex& p1, const Complex& p2); 25 }; 26 27 Complex operator + (const Complex& p1, const Complex& p2) 28 { 29 Complex ret; 30 31 ret.a = p1.a + p2.a; 32 ret.b = p1.b + p2.b; 33 34 return ret; 35 } 36 37 int main() 38 { 39 40 Complex c1(1, 2); 41 Complex c2(3, 4); 42 Complex c3 = c1 + c2; // c1 + c2 ==> operator + (c1, c2);用 “+” 来操作两个类,编译器没能力,然后编译器查找有没有用重载的概念扩展操作符的功能,于是找到了 operator +() 这个函数,如果编译器成功匹配相应的参数,则成功调用 operator +() 函数; 43 44 printf("c3.a = %d, c3.b = %d ", c3.getA(), c3.getB()); 45 46 return 0; 47 }
2,输出结果:
1,c3.a = 4, c3.b = 6
3,问题:
1,这里的解决方案用了友元,现代软件开发不允许;
2,是否可以提供成员函数代替全局函数,以抛弃友元?
6,可以将操作符重载函数定义为类的成员函数:
1,比全局操作符重载函数少一个参数(左操作数);
1,和全局函数最大的差异;
2,成员函数中隐藏的 this 参数可以充当左操作数的角色;
2,不需要依赖友元就可以完成操作符重载;
3,编译器优先在成员函数中寻找操作符重载函数;
1,一旦在成员函数中找到,就不会去全局找;
4,代码示例:
1 class Type 2 { 3 public: 4 Type operator Sign(const Type& p) // 左操作数用 this; 5 { 6 Type ret; 7 8 return ret; 9 } 10 };
7,成员函数重载操作符编程实验:
1,main.cpp 文件:
1 #include <stdio.h> 2 3 class Complex 4 { 5 int a; 6 int b; 7 public: 8 Complex(int a = 0, int b = 0) 9 { 10 this->a = a; 11 this->b = b; 12 } 13 14 int getA() 15 { 16 return a; 17 } 18 19 int getB() 20 { 21 return b; 22 } 23 24 Complex operator + (const Complex& p) 25 { 26 Complex ret; 27 printf("Complex operator + (const Complex& p) "); 28 ret.a = this->a + p.a; 29 ret.b = this->b + p.b; 30 31 return ret; 32 } 33 34 friend Complex operator + (const Complex& p1, const Complex& p2); 35 }; 36 37 Complex operator + (const Complex& p1, const Complex& p2) 38 { 39 Complex ret; 40 printf("Complex operator + (const Complex& p1, const Complex& p2) "); 41 ret.a = p1.a + p2.a; 42 ret.b = p1.b + p2.b; 43 44 return ret; 45 } 46 47 int main() 48 { 49 50 Complex c1(1, 2); 51 Complex c2(3, 4); 52 Complex c3 = c1 + c2; // c1 + c2 ==> c1.operator + (c2) 53 54 printf("c3.a = %d, c3.b = %d ", c3.getA(), c3.getB()); 55 56 return 0; 57 }
2,输出结果:
Complex operator + (const Complex& p)
c3.a = 4, c3.b = 6
8,小结:
1,操作符重载是 C++ 的强大特性之一;
2,操作符重载的本质是通过函数扩展操作符的功能;
3,operator 关键字是实现操作符重载的关键;
4,操作符重载遵循相同的函数重载规则;
5,全局函数和成员函数都可以实现对操作符的重载;