输入和输出运算符

重载输出运算符

通常情况下,输出运算符第一个形参是一个非常量 ostream 对象的引用。之所以使用 ostream 是非常量是因为向流写入内容会改变其状态;而形参是引用是因为无法直接复制一个 ostream 对象。

第二个形参一般来说是一个常量的引用,该常量表示想要打印的类类型。采用引用可以避免复制实参;之所以是常量是因为通常情况下打印对象不会改变对象的内容。

operator<< 一般要返回它的 ostream 形参。

ostream &operator<<(ostream&os,const Sales_data &item)
{
	os<<item.isbn()<<" "<<item.units_sold<<" "<<item.revenue<<" "<<item.avg_price();
	return os;
}

注意:

通常,输出运算符应该主要负责打印对象的内容而非控制格式,输出运算符不应该打印换行符。

输入输出运算符必须是非成员函数

与 iostream 标准库兼容的输入输出运算符必须是普通的非成员函数,而不能是类的成员函数,否则,它们的左侧运算对象将是我们类的一个对象:

Sales_data data;
data << cout;	//如果operator<< 是Sales_data 的成员

通常 IO 运算符可能需要读写类的非公有数据成员,所以,IO 运算符一般被声明为友元。

重载输入运算符

通常情况下,输入运算符的第一个形参是运算符将要读取的流的引用,第二个形参是要读入到的对象的引用,该运算符返回某个给定流的引用。

istream &operator>>(istream &is,Sales_data &item)
{
	double price;
	is >> item.boolNo >> item.units_sold >> price;
	if(is)
		item.revenue = item.units_sold * price;
	else
		item = Sales_data;	//输入失败,对象被赋予默认状态
	return is;
}

输入时的错误

输入运算符必须处理输入可能失败的情况,而输出运算符不需要。

执行输入运算符时可能发生的错误:

  • 当流含有错误类型的数据时读取操作可能失败。例如在读取完 bookNo 后,输入运算符假定接下来读取的是两个数字,一旦输入的不是数字数据,则读取操作及后续对流的其他使用都将失败。
  • 当读取操作到达文件末尾或者遇到输入流的其他错误时也会失败。

程序中没有逐个检查读取操作,而是在读取完成后统一检查:

if(is)
		item.revenue = item.units_sold * price;
else
		item = Sales_data;	//输入失败,对象被赋予默认状态

当读取操作发生错误时,输入运算符应该负责从错误中恢复。

原文地址:https://www.cnblogs.com/xiaojianliu/p/12496403.html