Conclusion1:
流插入运算符需要被重载成全局函数。
一:流运算符的重载:
cout<<10<<endl;
cout是在iosream中定义的一个ostream对象
iostream中对“<<”进行了重载。 cout<<10; 即 cout.operator<<(10);
ostream & ostream::operator<<(int n){
……
return *this; // *this 就是cout
}
也就是说,cin和cout是定义在std namespace中的对象,通过cout<<10,其实就是调用的cout对象的成员函数,即out.operator<<(10);
因为cout是一个对象,所以其实在这里还是会添加一个this指针。
二:流插入运算符为什么要被重载为全局函数
假设有Complex对象c, 如果要用cout<<c来输出, 就要对“<<“重载。
但是
1)不能在ostream类中对"<<"重载,因为ostream类已经被封装好了。
2)不能在Complex类中对"<<"重载,否则*this对象会混淆。(主要是出于使用的习惯,下面介绍)
class Complex
{
public:
int a,b;
Complex(int n1, int n2):a(n1), b(n2){}
};
ostream &operator<<(ostream &os, Complex &x){ //cout<<x<<endl;
os<<x.a<<"+i"<<x.b;
return os;
}
<<运算符的重载,需要在类外进行定义,此时在其他的源文件使用cout<<来输出Complex对象的话,需要在声明该重载运算符。
extern ostream &operator<<(ostream &os, Complex &x);
这样是很不方便的,不满足C++的封装特性。
三:流运算符如何使用起来更方便?
使用友元函数,将流运算符重载为友元函数,这样在其他的源文件中使用的话,就只需要include头文件。
class Complex
{
public:
int a,b;
Complex(int n1, int n2):a(n1), b(n2){}
friend ostream &operator<<(ostream &os, Complex &x){ //cout<<x<<endl;
os<<x.a<<"+i"<<x.b;
return os;
}
};
使用友元函数还有一个好处,可以访问私有或者protected成员变量。
四:流运算符在类中重载
上面提到流运算符定义为全局函数,是为了符合使用的习惯。
如果我们把流运算符在类中进行重载:
class Complex
{
public:
int a,b;
Complex(int n1, int n2):a(n1), b(n2){}
ostream &operator<<(ostream &os){ //cout<<x<<endl;
os<<this->a<<"+i"<<this->b;
return os;
}
};
那么在使用的时候,
Complex cObj1(2,4);
cObj1<<cout<<endl;//相当于cObj1.operator<<(cout)
来源:CSDN
作者:corey_li
链接:https://blog.csdn.net/corey_li/article/details/103496389