余睿的博客

浮生若梦,别多会少,不如莫遇

0%

c++流插入和流提取运算符的重载

引入

问题

1
cout<<5<<"this";

上面语句为什么可以成立?

cout是什么?<<为什么可以作用在cout上?

解答

cout是在iostream中定义的ostream类的对象。<<能作用在cout是因为在iostream里对<<进行了重载。

考虑,怎样重载才能使得cout<<5;cout<<"this";都能成立。

重载<<运算符

假设按照以下的方法重载<<运算符

1
2
3
4
5
6
7
8
void operator<<(ostream& os, int n) {
//输出n
return;
}
void operator<<(ostream& os, const char* str) {
//输出str
return;
}

看起了似乎没有什么问题,而且也能实现cout<<5;cout<<"this";两个语句。

cout<<5相当于cout.operator<<(5);

cout<<"this"相当于cout.operator<<("this");

但是当我们想要输出cout<<5<<"this";时,就会出现问题了,因此我们需要修改上面的代码。

1
2
3
4
5
6
7
8
ostream& operator<<(ostream& os, int n) {
//输出n
return;
}
ostream& operator<<(ostream& os, const char* str) {
//输出str
return;
}

我们将两个函数的返回值改为ostream&,此时返回了一个ostream对象的引用,就可以识别cout<<5<<"this";这样的语句了,相当于cout.operator<<(5).operator<<("this");

样例

假设cComplex复数类的对象。现在希望写成cout<<c;就能以a+bi的形式输出c的值。写成cin>>c;就能接收a+bi形式的输入,并且c.real=ac.imag=b

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
class Complex {//复数类
private:
double real, imag;//实部、虚部
public:
Complex(int r = 0, int c = 0) {
real = r;
imag = c;
}
friend ostream& operator<<(ostream& os, const Complex& c);
friend istream& operator>>(istream& is, Complex& c);
};
ostream& operator<<(ostream& os, const Complex& c) {
//以a+bi的形式输出
os << c.real << "+" << c.imag << "i" << endl;
return os;
}
istream& operator>>(istream& is, Complex& c) {
string s;
is >> s;//将a+bi以字符串形式读入
int pos = s.find("+", 0);//找到+号位置
string real = s.substr(0, pos);//分离出代表实部的字符串
//atof能将const char*的内容转换为float
c.real = atof(real.c_str());
//分离出虚部字符串
string imag = s.substr(pos + 1, s.length() - pos - 2);
c.imag = atof(imag.c_str());
return is;
}

在上面的类实现中,我们将ostream& operator<<(ostream& os, const Complex& c)以及istream& operator>>(istream& is, Complex& c)函数声明为类Complex类的友元,这样就能访问Complex类的私有成员了。

主函数实现如下:

1
2
3
4
5
6
int main() {
Complex c1;
cin >> c1;
cout << c1;
return 0;
}

执行上面的代码,得到以下结果:

1
2
1+5i
1+5i

欢迎关注我的其它发布渠道