【GeekBand】Week02

一、关于流运算符(<<、>>)的重载问题###

首先考察一个实部虚部为double类型的复数complex类:

class complex
{
public:
  complex (double r = 0, double i = 0): re (r), im (i) { }
  //……
  double real () const { return re; }
  double imag () const { return im; }
private:
  double re, im;
  //……
};

<<操作符进行重载,使cout能够以“(x + yi)”的格式输出complex对象时,可以这么做:

ostream& operator<<(ostream& os, const complex& c)
{
   os << "(" << c.real() << " + " << c.imag() << "i)";
   return os;
}

如果不想调用real()imag(),想直接访问reim这两个私有成员,那么我们要把operator <<定义为complex类的友元函数:

class complex
{
  //……
  //在complex类里声明友元
public:
  friend ostream& operator<<(ostream& os, const complex& c);
  //……
};

ostream& operator<<(ostream& os, const complex& c)
{
   os << "(" << c.re << " + " << c.im << "i)";
   return os;
}

那么,为什么不能把<<运算符直接重载为complex类的成员函数呢?这样不用声明友元不也可以访问私有成员了吗?
假如真的这么做了,那么我们的代码应该是这个样子:

class complex
{
public:
  //……
  ostream& operator<<(ostream& os, const complex& c);
//……
};

但是这是成员函数呀,前面还应该有个隐含的this指针才对,<<是双目运算符,只能接收两个参数,所以这么写不对;
那我们重载<<的目的就是为了将complex对象的输出格式放到cout里,所以只好改成这样:

class complex
{
public:
  //……
  ostream& operator<<(ostream& os);
//……
};

//<<的实现
ostream& complex::operator<<(ostream& os)
{
   os << "(" << c.re << " + " << c.im << "i)";
   return os;
}

然后用的时候,因为成员运算符函数固定左值为该类的对象,所以只好写成这样:

complex c1(1, 2);
c1 << cout;

和我们平时用的cout << c1这样格式方向相反,非常别扭,
而且如果要实现连续输出cout << c1 << c2 << ......,呃,不对,现在的例子应该是...... << c2 << c1 << cout,除了最右边那个<<可以调用,其他的<<因为接收的参数是complex类型,所以我们还要进行一次重载。种种麻烦说明,还是老老实实把<<重载写在类外面,或者声明友元好了。

你可能感兴趣的:(【GeekBand】Week02)