【C++】重載輸入輸出運算符

重載輸入輸出運算符

我們平時可以用流 std::cout<<str<<n ; std::cin>>str>>n ; 輸出、輸入字符串和整型等內置類型的值。但是對於我們自定義的類,比如 Student 類,卻不能直接通過 cout<<Student 或 cin>>Student 這樣的形式來輸出類的內容或給類賦值。怎麼辦呢?我們可以通過重載輸出、輸入運算符,讓自定義的類也支持這樣的操作。

重載輸出運算符

  1. 通常情況下,輸出運算符的第一個形參是一個非常量的ostream 對象的引用。(非常量是因爲向流寫入內容會改變其狀態; 用引用是因爲流對象不支持複製)
  2. 第二個參數一般來說是一個常量的引用,該常量是我們想要輸出的類類型。(用引用是因爲我們希望避免複製實參; 用常量是因爲通常打印對象的時候不需要改變對象的內容)
  3. 輸出運算符應儘量減少格式化的操作,尤其是換行符,這樣有利於用戶對輸出格式的控制。
  4. 一般會聲明爲友元函數(friend),這樣輸出運算符函數才能使用類的私有成員
  5. 輸入、輸出運算符都必須是非成員函數。否則,他們的左側運算對象將是我們的類的一個對象。
//例如,假設我們定義了類Student,輸出運算符函數爲成員函數
class Student{
 ...
 ostream  &operator<<(ostream &os);
 ...
};
...
Student    stu;
//爲了直觀,用這種方式調用輸出運算符函數
stu.operator<<(cout);   //等價於,stu<<cout ,顯然已經錯了
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  1. 下面是一個例子:
#include<iostream>
using namespace std;
class Student
{
    public:
        Student(int x,string s)
        {
            num  = x;
            name = s;
        }
    friend  ostream  &operator<<(ostream &os,const Student &stu);  //聲明爲友元
    private:
        int      num;
        string   name;
};

ostream  &operator<<(ostream &os,const Student &stu)
{
    os<<stu.num<<" "<<stu.name;
    return os;
}

int main()
{
    Student  stu(10,"liu");

    //調用者在使用的時候決定是否換行
    cout<<stu<<endl;

    return 0;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31

這裏寫圖片描述

重載輸入運算符

  1. 通常情況下,輸入運算符的第一個形參是運算符將要讀取的流的引用,第二個形參是將要讀入到的(非常量)對象的引用。(第二個形參非常量是因爲目的就是將數據讀入對象中,所以對象會被改變。)
  2. 該運算符通常會返回某個給定流的引用。
  3. 輸入運算符必須處理輸入可能失敗的情況,而輸出運算符不需要。

輸入時會發生的錯誤

可能會發生下列錯誤: 
1. 當流含有錯誤類型的數據時讀取操作可能失敗(輸入數據與類型不匹配)。一旦發生錯誤,後續的流使用都將失敗。 
2. 當讀取操作到達文件末尾或者遇到輸入流的其他錯誤時也會失敗。

檢查輸入是否成功

如果我們不進行錯誤判斷,可能會出現對象只有部分成員被賦了值,另外的成員未被賦值或賦值錯誤,這很可能導致該對象在以後的使用過程中引發錯誤。

解決的辦法是,對輸入結果進行判斷,如果輸入失敗,則將一個新的默認初始化的對象賦值給操作對象。

下面是一個例子(將上一個例子修改):

class Student
{
    public:
        //構造函數,列表初始化
        Student():num(0),name(""){}
    //重載輸出運算符    
    friend  ostream  &operator<<(ostream &os,const Student &stu);  //聲明爲友元
    //重載輸入運算符
    friend  istream  &operator>>(istream &is,Student &stu);
    private:
        int      num;
        string   name;
};

ostream  &operator<<(ostream &os,const Student &stu)
{
    os<<stu.num<<" "<<stu.name;
    return os;
}

istream  &operator>>(istream &is,Student &stu)
{
    is>>stu.num>>stu.name;
    //輸入判斷
    if(!is)
        stu = Student(); //如果失敗,默認初始化
    return is;
}

int main()
{
    Student  stu;
    cout<<"input:"<<endl;
    //調用重載的輸入運算符函數
    cin>>stu;

    cout<<"output:";
    //調用者在使用的時候決定是否換行
    cout<<stu<<endl;

    return 0;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42

這裏寫圖片描述

轉自:http://blog.csdn.net/lyh__521/article/details/49601489
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章