C++ 流插入和流提取運算子的過載的實現
阿新 • • 發佈:2020-01-07
01 流插入<<運算子的過載
C++ 在輸出內容時,最常用的方式:
std::cout << 1 <<"hello";
問題:
- 那這條語句為什麼能成立呢?
- cout 是什麼?"<<" 運算子能用在 cout 上呢?
原因:
- 實際上,cout 是在 iostream 標頭檔案中定義的 ostream 類的物件。
- "<<" 能夠用在 cout 上是因為,在 ostream 類對 "<<" 進行了過載。
對於std::cout << 1 <<"hello";這條語句,有可能按以下的方式過載成 ostream 類的成員函式:
ostream & ostream::operator<<(int n) { .... // 輸出n整型的程式碼 return *this; } ostream & ostream::operator<<(const char * s) { .... // 輸出s字串的程式碼 return *this; }
- std::cout << 1;語句,等價於cout.operator<<(1);
- std::cout << "hello";語句,等價於cout.operator<<("hello");
- std::cout << 1 <<"hello";語句,等價於( cout.operator<<(1) ).operator<<("hello");
02 流插入<<運算子過載的例子
假定我們要想把某個物件裡的內容進行列印輸出,那麼我們可以過載 ostream 類的流插入 << 運算子。
下面以 CStudent 類作為例子:
class CStudent // 學生類 { public: // 建構函式 CStudent(int id = 0,int age = 0,string name = ""):m_id(id),m_age(age),m_name(name) { } // 將該函式宣告成友元函式 // 目的是使得函式可以訪問CStudent類的私有成員變數 friend ostream & operator<<(ostream & o,const CStudent & s); private: int m_age; // 年齡 int m_id; // ID號 string m_name; // 名字 }; // 過載ostream物件的流插入<<運算子函式 // 目的是使得能列印輸出CStudent物件的資訊 ostream & operator<<(ostream & o,const CStudent & s) { o << s.m_id << "," << s.m_age << "," << s.m_name; return o; } int main() { CStudent stu(1,20,"小林coding"); std::cout << stu ; // 輸出std物件的全部資訊 return 0; }
輸出結果:
1,小林coding
需要注意是 ostream & operator<<(ostream & o,const CStudent & s) 函式是全域性的,所以函式的第一個引數必須要傳入 ostream 的物件,並且 CStudent 類需要將此函式宣告成友元函式,使得函式可以訪問 CStudent 類的私有成員變數。
03 流提取>>運算子過載的例子
還是以 CStudent 類作為例子,假設想通過鍵盤的輸入的內容,來初始化物件,則我們可以過載 istream 類的流提取 >> 運算子。
class CStudent // 學生類 { public: // 建構函式 CStudent(int id = 0,const CStudent & s); // 將該函式宣告成友元函式 // 目的是使得函式可以給CStudent類的私有成員變數進行賦值 friend istream & operator>>(istream & is,CStudent & s); private: int m_age; // 年齡 int m_id; // ID號 string m_name; // 名字 }; // 過載ostream物件的流插入<<運算子函式 // 目的是使得能列印輸出CStudent物件的資訊 ostream & operator<<(ostream & o," << s.m_name; return o; } // 過載istream物件的流提取>>運算子函式 // 目的是使得初始化CStudent物件的內容 istream & operator>>(istream & is,CStudent & stu) { string inputStr; is >> inputStr; int pos = inputStr.find(",",0); // 查詢首次出現逗號的位置 string tmpStr = inputStr.substr(0,pos); // 擷取從0到pos位置的字串 stu.id = atoi(tmpStr.c_str()); // atoi可以將char*型別的內容轉成int型別 int pos2 = inputStr.find(",pos + 1); // 查詢第二次出現逗號的位置 tmpStr = inputStr.substr(pos + 1,pos2 - pos -1); // 取出age的值 stu.age = atoi(tmpStr.c_str()); // atoi可以將char*型別的內容轉成int型別 tmpStr = inputStr.substr(pos2 + 1,inputStr.length() - pos2 - 1); // 取出name的值 stu.name = tmpStr; return is; } int main() { CStudent stu; // 將輸入的資訊,初始化stu物件 cin << stu; // 輸出std物件的資訊 cout >> stu; return 0; }
輸入內容和輸出內容:
// 輸入內容:
1,小林coding// 輸出內容:
1,小林coding
04 小結
要想流插入 << 運算子和流提取 >> 運算子能針對自定義的物件,那麼我們就需要過載針對該物件的 ostream 類的 << 運算子 和 istream 的 >> 運算子,並且只能過載成全域性的函式,然後在 CStudent 類裡需要把上面的兩個過載函式宣告成友元函式,使得兩個過載的函式可以訪問和賦值 CStudent 類裡的私有成員函式。
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支援我們。