本文主要介绍输入操作符>>和输出操作符<<的重载。在那之前,我们先思考一个问题:+、-、*、/等双目运算符以及++、--等单目运算符,他们的操作数有什么共同之处呢?仔细想想,他们的左操作数都是自身的类对象,比如+运算符的重载:
上面采用类的成员函数的重载形式,请大家不要忘记函数里面还隐藏包含一个this指针作为左操作数。我们再来看下用友元函数形式重载的前++操作符:
输入操作符:
不知道细心的你有没有发现,输出输出操作符的左操作数明显不能是我们自定义的类了,因为他们分别是cout和cin这个ostream和istream对象,这样的话我们就无法再我们自定义类中实现对<<和>>的重载了。
对!实现对输入和输出操作符的重载,只能使用友元函数的形式!这就是<<和>>与其他操作符的不同。ostream和istream的内部,实现了对所有C++基本类型的重载,此时,因为ostream和istream为左操作数,所有重载函数都被定义成了成员函数的形式。这一点,我们可以查看/usr/include/c++/4.4.4/中ostream头文件,找到很多类似下面这种对基本类型的重载函数声明:
第7行和第12行分别定义了输入操作符>>和输出操作符<<的重载函数,两者的参数完全相同,但是返回值有很大的区别。主要因为输入操作符是向右操作数中输入数据,改变的是重载函数中的右操作数,所以返回了带有const属性的istream对象的引用;而输出操作数是向输出流中输入数据,改变的是重载函数中的左操作数,所以需要返回不带const属性的ostream引用。
在主函数中我们先定义了一个Integer对象,然后由用户输入一个数字,再通过cout打印到标准输出,如果程序运行结果正确,则证明我们重载正确。请看下面的结果:
const Integer operator+(const Integer& that) const;
上面采用类的成员函数的重载形式,请大家不要忘记函数里面还隐藏包含一个this指针作为左操作数。我们再来看下用友元函数形式重载的前++操作符:
friend Integer& operator++(Integer& ts);
这里显式的添加了我们自定义的类对象Integer作为左操作数。综上所述,前面介绍过的操作符的重载都是以我们自定义的类对象为左操作数。而输出和输入操作符不同,我们来看下输出和输入操作符的一个使用例子:
输出操作符: cout<<"hello word"<<endl;
输入操作符:
int i;
cin>>i;
不知道细心的你有没有发现,输出输出操作符的左操作数明显不能是我们自定义的类了,因为他们分别是cout和cin这个ostream和istream对象,这样的话我们就无法再我们自定义类中实现对<<和>>的重载了。
对!实现对输入和输出操作符的重载,只能使用友元函数的形式!这就是<<和>>与其他操作符的不同。ostream和istream的内部,实现了对所有C++基本类型的重载,此时,因为ostream和istream为左操作数,所有重载函数都被定义成了成员函数的形式。这一点,我们可以查看/usr/include/c++/4.4.4/中ostream头文件,找到很多类似下面这种对基本类型的重载函数声明:
__ostream_type&
operator<<(int __n);
接下来我们生命自己的自定义类的输入和输出操作符重载函数,由于比较简单,只列出代码:
#include<iostream>
using namespace std;
class Integer
{
private:
int m_i;
friend const istream& operator>>(istream& in,Integer& i)
{
in>>i.m_i;
return in;
}
friend ostream& operator<<(ostream& out,Integer& i)
{
out<<(i.m_i);
return out;
}
};
int main()
{
Integer i;
cout<<"plesae input a num:"<<endl;
cin>>i;
cout<<"the num inputed is:"<<i<<endl;
return 0;
}
第7行和第12行分别定义了输入操作符>>和输出操作符<<的重载函数,两者的参数完全相同,但是返回值有很大的区别。主要因为输入操作符是向右操作数中输入数据,改变的是重载函数中的右操作数,所以返回了带有const属性的istream对象的引用;而输出操作数是向输出流中输入数据,改变的是重载函数中的左操作数,所以需要返回不带const属性的ostream引用。
在主函数中我们先定义了一个Integer对象,然后由用户输入一个数字,再通过cout打印到标准输出,如果程序运行结果正确,则证明我们重载正确。请看下面的结果:
[Hyman@Hyman-PC operator]$ g++ operatorci.cpp
[Hyman@Hyman-PC operator]$ ./a.out
plesae input a num:
123
the num inputed is:123
ok,结果正确。