1.假设<<,>>可以作为成员函数
(1)假设输入输出运算符是某个类的成员,那么要以正常形式使用(流对象在左),则它们也必须是istream或ostream的成员。然而,这两个类属于标准库,并且我们无法给标准库中的类添加任何成员。
可能有人会不理解这个流对象在左边为什么一定要是istream和ostream类的成员,这里补充说明:
对于成员函数,其左侧运算对象必须是运算符所属类的一个对象。也就是说左侧的这个对象必须和运算符必须同属一个类,否则当其他类的对象调用该符号 << 时,在其他类内找不到该符号的成员函数。
有人会提出疑问:那我们不让<<左边为iostream类不就可以了吗?
按照思路确实可以:
此时a<<cout ,相当于a.operator<<cout,我们习惯于cout在前,输出对象在后,所以此种方式也不采纳。
2.解释一下为什么重载为友元以及全局函数
iostream和ostream类不能添加成员变量以及成员函数,既然他们不能加,我们就换个角度,将<<,>>重载为全局函数,想用直接使用就可以,不用在类中添加了,但是要访问私有成员,光有全局函数是不行的,所以在我们所定义的类中声明重载的<<,>>函数为其友元函数,重载的<<,>>函数也就具有了访问类的私有成员变量以及执行其他与类相关的操作的权利。
当定义为非成员函数后,左值的数据类型为参数列表第一个的数据类型,左值的数据类型可以随意定义。实际调用时根据左右值的数据类型调用对应的函数。
此时就不用拘泥于数据类型了,如cout<<c,被解释为operator(cout,c),就很容易确定两个参数了,并且输出方式也符合人类思维。
补充:ostream& operator <<(ostream &cout,const Complex & c)//Complex为自己定义的类,
函数返回类型为ostream的引用,是为了连续输出,引用可以作为左值,
如:cout<<a<<b;a,b均为Complex类型,等同于operator.(operator.(cout+b)+b),其中operator.(cout+b)类型依旧为ostream,符合要求,可以连续输出。