C++裏面,我們想打印類的信息,需要重載<<運算符,這篇博客將介紹如何重載<<運算符打印類消息。並且介紹這麼做的一些規則和原因。
重載<<運算符打印自定義類信息
我們用代碼來進行說明:我們定義一個Person類,想要打印出Person類實例的age屬性。
Person
{
private:
int age_;
public:
void SetAge(int age)
{
age_ = age;
}
}
int main()
{
Person a;
a.SetAge(10);
cout << a << endl;
}
這樣寫肯定會報錯,運行失敗的(頭文件引用,命名空間等偷懶了沒寫,不要在意這些細節)。我們想要 cout << a自動打印出年齡怎麼辦?
我們這麼寫,多加一個重載<<運算符的方法:
class Person
{
int age_;
public:
void SetAge(int age)
{
this->age_ = age;
}
friend ostream &operator<<(ostream &stream, const Person &p)
{
stream << p.age_ << endl;
return stream;
}
};
int main()
{
Person a;
a.SetAge(10);
cout << a << endl;
}
運行程序可以看到打印出了10。
在這裏,我們用一個友元函數來進行<<運算符重載,這個友元函數有個固定的格式:
friend ostream &operator<<(ostream &stream, const Person &p)
{
stream << p.age_ << endl;
return stream;
}
爲了與IO標準庫一致,要返回一個ostream對象的引用,接受兩個參數,第一個參數是對一個ostream對象的應用,,第二個參數爲一個想要打印的類類型對象的引用,你想要cout<<打印一個Person類,第二個參數就傳入一個Person類的引用,這個函數也要定義成友元類。
爲什麼要把這個<<運算符重載定義爲友元類
從語法上來說,我們的確可以把這個函數定義爲類成員函數的,如下:
class Person
{
int age_;
public:
void SetAge(int age)
{
this->age_ = age;
}
ostream &operator<<(ostream &stream)
{
stream << age_ << endl;
return stream;
}
};
int main()
{
Person a;
a.SetAge(11);
a << cout;
}
就如代碼裏所示,我們把關鍵字friend去掉了,把第二個參數給去掉了,然後使用a << cout來打印類信息了。可以看到,如果這樣定義,和其它類型的輸出操作符相反了。
下面引用一段C++primer裏的一段話:
相反,如果想要使用重載操作符爲該類型提供 IO 操作,就必須將它們定義
爲非成員函數。IO 操作符通常對非公用數據成員進行讀寫,因此,類通常將 IO
操作符設爲友元。
也就是說,IO操作符重載函數,通常被定義爲友元函數。