原文链接:http://blog.csdn.net/lyh__521/article/details/49601489
重载输入输出运算符
我们平时可以用流 std::cout<<str<<n ; std::cin>>str>>n ; 输出、输入字符串和整型等内置类型的值。但是对于我们自定义的类,比如 Student 类,却不能直接通过 cout<<Student 或 cin>>Student 这样的形式来输出类的内容或给类赋值。怎么办呢?我们可以通过重载输出、输入运算符,让自定义的类也支持这样的操作。
重载输出运算符
- 通常情况下,输出运算符的第一个形参是一个非常量的ostream 对象的引用。(非常量是因为向流写入内容会改变其状态; 用引用是因为流对象不支持复制)
- 第二个参数一般来说是一个常量的引用,该常量是我们想要输出的类类型。(用引用是因为我们希望避免复制实参; 用常量是因为通常打印对象的时候不需要改变对象的内容)
- 输出运算符应尽量减少格式化的操作,尤其是换行符,这样有利于用户对输出格式的控制。
- 一般会声明为友元函数(friend),这样输出运算符函数才能使用类的私有成员
- 输入、输出运算符都必须是非成员函数。否则,他们的左侧运算对象将是我们的类的一个对象。
//例如,假设我们定义了类Student,输出运算符函数为成员函数
class Student{
...
ostream &operator<<(ostream &os);
...
};
...
Student stu;
//为了直观,用这种方式调用输出运算符函数
stu.operator<<(cout); //等价于,stu<<cout ,显然已经错了
- 下面是一个例子:
#include<iostream>
using namespace std;
class Student
{
public:
Student(int x,string s)
{
num = x;
name = s;
}
friend ostream &operator<<(ostream &os,const Student &stu); //声明为友元
private:
int num;
string name;
};
ostream &operator<<(ostream &os,const Student &stu)
{
os<<stu.num<<" "<<stu.name;
return os;
}
int main()
{
Student stu(10,"liu");
//调用者在使用的时候决定是否换行
cout<<stu<<endl;
return 0;
}
重载输入运算符
- 通常情况下,输入运算符的第一个形参是运算符将要读取的流的引用,第二个形参是将要读入到的(非常量)对象的引用。(第二个形参非常量是因为目的就是将数据读入对象中,所以对象会被改变。)
- 该运算符通常会返回某个给定流的引用。
- 输入运算符必须处理输入可能失败的情况,而输出运算符不需要。
输入时会发生的错误
可能会发生下列错误:
1. 当流含有错误类型的数据时读取操作可能失败(输入数据与类型不匹配)。一旦发生错误,后续的流使用都将失败。
2. 当读取操作到达文件末尾或者遇到输入流的其他错误时也会失败。
检查输入是否成功
如果我们不进行错误判断,可能会出现对象只有部分成员被赋了值,另外的成员未被赋值或赋值错误,这很可能导致该对象在以后的使用过程中引发错误。
解决的办法是,对输入结果进行判断,如果输入失败,则将一个新的默认初始化的对象赋值给操作对象。
下面是一个例子(将上一个例子修改):
class Student
{
public:
//构造函数,列表初始化
Student():num(0),name(""){}
//重载输出运算符
friend ostream &operator<<(ostream &os,const Student &stu); //声明为友元
//重载输入运算符
friend istream &operator>>(istream &is,Student &stu);
private:
int num;
string name;
};
ostream &operator<<(ostream &os,const Student &stu)
{
os<<stu.num<<" "<<stu.name;
return os;
}
istream &operator>>(istream &is,Student &stu)
{
is>>stu.num>>stu.name;
//输入判断
if(!is)
stu = Student(); //如果失败,默认初始化
return is;
}
int main()
{
Student stu;
cout<<"input:"<<endl;
//调用重载的输入运算符函数
cin>>stu;
cout<<"output:";
//调用者在使用的时候决定是否换行
cout<<stu<<endl;
return 0;
}