天天看點

流運算符的重載

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