在学习对运算符的重载的时候,重载了++,--(前缀后缀),并且都是在定义为类中的成员函数。但是当我尝试去重载>>,<<为某一个类的成员函数的时候,就会报错,无论如何改参数的属性,位置,都不行,只有将<<,>>重载定义在全局,并且在这个类中将其声明为友元时,才能完成重载。
根据我们实践出真知的道理,我们确实可以得出输入输出运算符重载必须要重载为全局的,可是为什么?在思考了很久,最终还是在C++prime第五版的494面的找到了答案。
我总结一下,原因在于:
第一,假如我们在将其重载为类成员函数,那么这个运算符的左侧运算对象将是这个类的一个对象。比如说,Point是一个类,p1是其实例,那么使用<<时,需要写成p1 << cout,这样就和我们原来运用的cout << "hello world" << endl;不一致,有点反人类。
第二,也是最根本的原因,假如我们将其重载为类成员函数,那么因为这两个运算符需要用到类似std::cout,std:cin的流,而这些属于istream和ostream标准库中的成员,那么我们必须将我们重载的两个运算符添加进这两个标准库中才能完成调用,但是为标准库添加成员我们是做不到的,因此<<,>>不能声明为成员函数。
最后附上重载<<,>>,--(前缀后缀)的小案例:
<<,>>,--重载
1 #include <iostream> 2 using namespace std; 3 4 5 6 struct Point 7 { 8 int x; 9 int y; 10 11 public: 12 Point(int _x=0,int _y=0) 13 { 14 x = _x; 15 y = _y; 16 } 17 18 Point(Point &that) 19 { 20 x = that.x; 21 y = that.y; 22 } 23 24 25 26 27 Point& operator --(void) //前-- 28 { 29 --x; 30 --y; 31 return *this; 32 } 33 34 35 Point operator --(int) //后-- 36 { 37 Point t(*this); 38 --x; 39 --y; 40 return t; 41 } 42 43 44 Point operator *(Point &that) 45 { 46 Point t; 47 t.x = x*that.x; 48 t.y = y*that.y; 49 return t; 50 } 51 52 53 54 friend istream & operator >> (istream &is,Point &p1); 55 friend ostream &operator <<(ostream &os,Point &p1) 56 57 }; 58 59 60 ostream &operator <<(ostream &os,Point &p1) 61 { 62 return os << p1.x << p1.y; 63 } 64 65 istream &operator >> (istream &is,Point &p1) 66 { 67 return is >> p1.x >> p1.y; 68 } 69 70 71 72 73 int main() 74 { 75 Point p1(1,2); 76 (--p1).show(); 77 Point p2(2,3); 78 (p2--).show(); 79 80 81 Point p3; 82 cin >> p3; 83 p3.show(); 84 cout << p3 << endl; 85 86 } 87 88 89 90 91 92