输入和输出运算符
IO标准库通过<<和>>为内置类型定义了读写的版本,而类需要自定义合适其对象的新版本以支持IO操作。
1.重载输出运算符<<
①输出运算符的形参:
- 第一个形参是一个非常量ostream对象的引用。非常量是因为需要向流写入内容,这会改变其状态;引用是因为我们无法拷贝一个ostream对象,只能对其进行引用。
- 第二个形参是一个常量引用,是我们想打印类对象的内容,引用避免进行拷贝,而且我们不希望改变其内容,所以用常量引用。
- 类似其他内置类型的<<操作符,重载的<<需要返回自身的引用。
②输出运算符的注意事项:
-
输出运算符应尽量减少格式化操作:如果运算符打印了换行符,则用户就无法在同一行内接着打印一些描述性的文本,输出运算符不应该打印换行符。
-
**输入输出运算符必须是非成员函数:**否则,左侧运算对象将是我们的一个类。
如Sales_data输出运算符
ostream& operator<<(ostream &os, const Sales_data &rhs) {
os << rhs._isbn() << " " << rhs._sold << " "
<< rhs._revenue << " ";
return os;
}
2.重载输入运算符>>
①输入运算符的形参:
- 第一个形参是运算符将要读取的流的引用:理由同输出运算符。
- 第二个形参是将要读入到的非常量引用:因为输入运算符本身的目的就是将数据读入到这个对象中,因此这个对象会改变。
②输入运算符可能会出现错误需要处理失败的情况,而输出运算符不需要
在执行输入运算符时可能会发生下列错误:
- 当流含有错误类型的数据时读取操作可能失败。例如想要读取的是int类型,输入的却是string类型会发生错误。
- 当读取操作到达文件末尾或者输入流遇到其他错误时也会失败。
读取操作不会逐个检查每个读取操作,而是读取了所有的数据后赶在使用这些数据前进行一次性检查。
当读取操作发生错误时,输入运算符应该负责从错误中恢复。
如:Sales_data的输入运算符
istream& operator>>(istream &is, Sales_data &rhs) {
double price;
is >> item._bookNo >> item._sold >> price;
if (is) {
item._revenue = item._sold * price;
} else {
item = Sales_data(); //读取失败则值初始化。
}
}