C++

C++ - 为什么流运算符必须要friend

Posted by Peinan on October 13, 2019

学C++也很久了,但是一直不知道为什么运算符重载里唯独«和»两个流运算符需要友元/friend标志。

首先要明确,作为成员函数的操作符重载必定隐含第一个操作数为this指针。

看下面这几行语句

1
2
3
x + 1;

cout << x;

有什么区别?假设x都是int型,第一句的操作数依次为x和1,第二句的操作数依次为cout和x。

问题就在这里了为什么都是对int类型的二元操作符(重载),一个x写前面一个x写后面呢?

由此展开cout/cin写在最前面有两个原因

  1. 看的更清楚 明确输出语句和输入语句

  2. 为了连续表达式 比如cout « x « y « z;

这样一来就很好理解了,因为在类里面定义的操作符重载第一个操作数必须且必为隐含的this,所以没办法把cout放到前面去,如果你接受

1
x << cout;

那么你也可以直接把函数定义为

1
ostream& operator<< (ostream& os);	// 对于二元运算符/binary operator,只需要1个参数+1个隐含参数

这种情况完全不影响cout的使用,但是没法连续输出,因为形似

1
y << x << cout;

这样的语句是非法的(«执行顺序都是从左到右的),这种情况下你要不就选择加括号

1
y << (x << cout);

但是这治标不治本,层数多了没人受得了。

因此为了连续操作,不能把流运算符重载作为类成员函数,friend就由此而来了,即使在类内定义,也强制转成非成员函数。