关系运算符的重载
IO标准库使用“>>”和“<<”运算符执行输入输出操作,对于这两个运算符来说,IO库定义了其基本数据类型的操作,但若要直接对类对象进行输入输出,则需要在类中重载这两个运算符。
输入输出运算符只能重载成类的非成员函数,因为它们左侧的运算对象必须是istream/ostream,而如果重载成类的成员函数,则左侧的操作对象将是我们定义的一个类对象。重载“<<”和“>>”运算符的一般格式如下所示:
ostream& operator<<(ostream&, const 类对象引用);
istream& operator>>(istream&, 类对象引用);
对于输出运算符“<<”来说,第一个参数是ostream对象引用,因为向流中写入数据会改变流的状态,所以不能用const修饰ostream对象。对于输入运算符来说,第一个参数是istream对象的引用,第二个参数要向其中存入数据的对象,不能为常量。
为了加深读者对“<<”和“>>”运算重载的理解,接下来通过一个案例来重载两个运算符,具体代码如例1所示。
例1
1 #include <iostream>
2 using namespace std;
3 class A
4 {
5 private:
6 int x;
7 int y;
8 public:
9 A(int x1 = 0, int y1 = 0):x(x1), y(y1){}
10 friend ostream& operator<< (ostream& os, const A& a); //重载<<运算符
11 friend istream& operator>> (istream& is, A& a); //重载>>运算符
12 };
13 ostream& operator<< (ostream& os, const A& a)
14 {
15 os << "(" << a.x << "," <<a.y << ")"; //输出类的数据成员
16 return os;
17 }
18 istream& operator>> (istream& is, A& a)
19 {
20 is >> a.x >> a.y; //输入类的成员数据
21 return is;
22 }
23 int main()
24 {
25 A a1(1, 2), a2(3, 4);
26 cout <<"a1:"<< a1 << endl;
27 cout << "a2:" << a2 << endl;
28
29 cout << "请重新为a2对象输入数据:" << endl;
30 cin >> a2;
31 cout << "重新输入后a2:" << a2 << endl;
32
33 system("pause");
34 return 0;
35 }
运行结果如图1所示。
图1 例1运算结果
由图1所知,例1中重载“<<”和“>>”运算符成功,这样便可以像基本数据类型一样直接对类对象进行输入输出,不用再编写例4-1中的show()成员函数,而且使用起来更为简洁。
注意:通常情况下,输出运算符主要负责输出对象的内容,而非控制格式,此时不应该把换行符也重载进去。如果把换行符也重载进去,用户有时想在同一行输出一些描述性的文本,就无法完成了。因此,在重载输出运算符时,应尽量少一些格式化操作,可以使用户控制更多输出细节。