输入流、输出流: operator<<(ostream& ostream, Widget const&)
#
一般地, 定义为友元函数.
简易版#
1#include <istream> // for std::istream
2#include <ostream> // for std::ostream
3
4class Widget {
5 public:
6 // 将类成员写入流中
7 friend std::ostream& operator<<(std::ostream& ostream, Widget const& widget) {
8 ostream << widget.value_;
9 return ostream; // 按引用返回输出流
10 }
11
12 // 从流中读取数据
13 friend std::istream& operator>>(std::istream& istream, Widget& widget) {
14 istream >> widget.value_;
15 return istream; // 按引用返回输入流
16 }
17
18 private:
19 int value_;
20};
复杂版#
提示
相比于进行这样的复杂实现来序列化, 你可能更想用第三方库进行序列化.
以按 (real,imaginary)
格式读入复数为例:
定义
operator<<
# 1#include <iomanip> // for std::setprecision
2#include <ostream> // for std::ostream
3#include <sstream> // for std::ostringstream
4
5class Complex {
6 public:
7 // 将复数以保留两位小数的 (real,imaginary) 写入流中
8 friend std::ostream& operator<<(std::ostream& ostream,
9 Complex const& complex) {
10 // 为避免污染 `ostream` 的格式, 新建一个 `std::ostringstream`
11 std::ostringstream oss;
12
13 oss << std::fixed << std::setprecision(2);
14 oss << '(' << complex.real_ << ',' << complex.imaginary_ << ')';
15
16 return ostream << oss.str();
17 }
18
19 private:
20 double real_;
21 double imaginary_;
22};
定义
operator>>
# 1#include <istream> // for std::istream
2
3class Complex {
4 public:
5 // 从流中读取 (real,imaginary) 为复数
6 friend std::istream& operator>>(std::istream& istream, Complex& complex) {
7 bool is_good = false; // 记录输入是否成功
8
9 // 从流中读取特定格式的数据, 并暂存在变量中
10 double real = 0;
11 double imaginary = 0;
12 if (istream >> std::ws // 忽略输入中最前面的所有空白符
13 && istream.get() == '('
14 && istream >> real
15 && istream.get() == ','
16 && istream >> imaginary
17 && istream.get() == ')') {
18 is_good = true; // 输入成功
19 }
20
21 if (is_good) {
22 // 如果读取完全成功, 更新 complex
23 complex.real_ = real;
24 complex.imaginary_ = imaginary;
25 } else {
26 // 如果读取失败, 设置 istream 为失败状态
27 istream.setstate(std::ios_base::failbit);
28 }
29
30 return istream;
31 }
32
33 private:
34 double real_;
35 double imaginary_;
36};