友元对重载操作符的影响?该怎么解决

友元对重载操作符的影响?
class   Complex
{
public:
Complex():_real(0),_image(0){}
Complex(double   d1,double   d2):_real(d1),_image(d2){}
Complex   &   operator   +(const   Complex   &C1);
friend   ostream&   operator < <(ostream   &,const   Complex   &);//此处如果不加friend,就会编译出错
//private://注意,此处始终是注释起来的
double   _real;
double   _image;
};
Complex   &   Complex::operator   +(const   Complex   &C1)
{
this-> _real+=C1._real;
this-> _image+=C1._image;
return   *this;
}

ostream&   operator < <(ostream   &ou   ,const   Complex   &C1)
{
cout < <C1._real < < "+ " < <C1._image < < "i ";
return   ou;
}
int   main(     )
{
Complex   C1(3,4);
Complex   C2(5,6);
Complex   C;
C=C1+C2;
cout < <C < <endl;
 
  return   0;
}
为什么加上friend说明就正确,而不加就编译不过呢?

------解决方案--------------------
不加friend是声明成员函数。
------解决方案--------------------
为什么加上friend说明就正确,而不加就编译不过呢?
-----------------------------------------------
你如果不加friend的话,就应该这样定义你的operator < <,如下
ostream& Complex::operator < <(ostream &ou ,const Complex &C1){//要加上“Complex::”,因为现在你在定义一个成员函数,必须加上域解析符
//...
}
------解决方案--------------------
不加friend是声明成员函数。
---------------------------
C++ Primer上说,成员操作符把隐含的this指针作为第一个参数。如果不加friend:
ostream& operator < <(ostream &,const Complex &);
则表示仍然是成员操作符而不是全局操作符,所以编译的时候提示参数太多,对吗?


是这样的, < <操作符只能有两个操作数,在类定义里声明成员函数要是象这样声明,实际上就是声明出3个操作数(包括类自身的this),显然不能通过编译。
------解决方案--------------------
宠载操作符也是函数的一种.
如果除子函数外的函数其他函数如果要访问private,protected,就必须进行友员声明,包括派生出来的类.所以如果你的重载操作符如果涉及到了private,protected成员,就应该声明友员.
(不过我好像在哪本书上看过:尽量不要声明友员,因为太多的友员会破坏类的隐蔽性).