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)
部分參考:https://www.cnblogs.com/XingyingLiu/p/5154871.html