重载输入输出操作符

本篇博客主要介绍两个操作符重载。一个是 <<(输出操作符)、一个是 >> (输入操作符)

现在就使用实例来学习:如何重载输入和输出操作符。

#include <iostream>
#include <string>

using namespace std;

int main(){

    cout << "hello" << endl;

    system("pause");
    return 0;
}

现在在程序里面定义一个 Sales_item 类。(Sales_item :销售单,销售项目。卖书的)

class Sales_item{

public:
    Sales_item(string &book, unsigned units, double price):
      isbn(book), units_sold(units), revenue(price*units){}
    Sales_item():units_sold(0), revenue(0.0){}

private:
    string isbn;
    unsigned units_sold;
    double revenue;
};

main() 函数中创建一个 Sales_item 类的对象,然后试着使用 << 输出操作符输出它。

int main(){
    Sales_item a;
    cout << a;

    system("pause");
    return 0;
}

会提示程序有错误,编译都不能通过。这是为什么?因为我们并没有重载 Sales_item 类的输出操作符,所以 cout << a; 这一行现在是错误的。
同样的道理:cin >> a; 这句代码也是错误的。

Sales_item 类现在即没有重载输入操作符,也没有重载输出操作符。现在,我们给他添加输入操作符重载的代码 和 输出操作符重载的代码。

重载输出操作符

main() 函数中创建一个 Sales_item 类的对象:


int main(){

    Sales_item item(string("0-201-78345-X"), 2, 25.00);

    system("pause");
    return 0;
}

我现在就像使用 cout << item << endl; 这段代码将 item 对象里面的内容输出。(现在在main() 函数中这样写是不行的,因为C++现在不知道如何输出这个对象。所以)我们需要编写输出操作符的重载代码。

重载输出操作符是比较简单的,把它做成一个友元函数,然后在输出的时候,直接将类的输出成员输出。

现在写一个函数。

输出操作符重载函数的返回结果 和 第一个形参 都必须是 ostream 类型,第二个形参就是 Sales_item 类型。

ostream& operator<<(ostream& out, const Sales_item& s){
    out << s.isbn << "\t" << s.units_sold << "\t" << s.revenue ;
    return out;
}

同时在 Sales_item 类里面的 public 里面,添加 对应的友元函数的声明:

class Sales_item{

public:

    friend ostream& operator<<(ostream& out, const Sales_item& s);

现在我们在main() 函数中添加测试代码:

int main(){

    Sales_item item(string("0-201-78345-X"), 2, 25.00);

    cout << item << endl;

    system("pause");
    return 0;
}

运行输出:

0-201-78345-X   2       25
请按任意键继续. . .

成功

编写输入操作符重载

输入操作符也有一个 输入流,类型为:istream 。输出操作符重载函数中第2个形参是 const 修饰,但是输入操作符重载函数的第2个形参就是不能使用 const 关键字修饰了,因为我们在函数里面会对这个形参里的数据进行修改。

istream& operator>>(istream& in, Sales_item& s){
    double price;
    in >> s.isbn >> s.units_sold >> price;

    s.revenue = s.units_sold * price;

    return in;
}

而且这个函数也要做成 Sales_item 类的友元函数。在 Sales_item 类中的 public 类里面添加下面的代码:

class Sales_item{

public:

    friend istream& operator>>(istream& in, Sales_item& s);

现在在 main() 函数中添加新的测试代码:

int main(){

    Sales_item item(string("0-201-78345-X"), 2, 25.00);

    cout << item << endl;
    cin >> item;
    cout << item << endl;

    system("pause");
    return 0;
}

运行代码:

0-201-78345-X   2       50
0-201-123
4
10
0-201-123       4       40
请按任意键继续. . .

对于输入操作符重载的函数的编写还没有完,我们一般要在代码中添加:处理输入操作的错误处理代码。(输出操作一般不会出错的,但是输入操作一般经常很容易出错。)比如说:数据的格式不对这样的错误。

我们可以使用 if 来检查输入流的状态,else 里面的就是出错了,我们就将 s 重新构造成一个空的对象。

istream& operator>>(istream& in, Sales_item& s){
    double price;
    in >> s.isbn >> s.units_sold >> price;

    if(in)
        s.revenue = s.units_sold * price;
    else
        s = Sales_item();

    return in;
}

在运行,看看:
输入正确的情况:

0-201-78345-X   2       50
0-201-43443-X
6
20
0-201-43443-X   6       120
请按任意键继续. . .

输入错误的情况:

0-201-78345-X   2       50
0-201-43343-X
aobosir
        0       0
请按任意键继续. . .


完整的代码:

#include <iostream>
#include <string>

using namespace std;

class Sales_item{

public:
    Sales_item(string &book, unsigned units, double price):
      isbn(book), units_sold(units), revenue(price*units){}
    Sales_item():units_sold(0), revenue(0.0){}

    friend ostream& operator<<(ostream& out, const Sales_item& s);
    friend istream& operator>>(istream& in, Sales_item& s);
private:
    string isbn;
    unsigned units_sold;
    double revenue;
};

ostream& operator<<(ostream& out, const Sales_item& s){
    out << s.isbn << "\t" << s.units_sold << "\t" << s.revenue ;
    return out;
}

istream& operator>>(istream& in, Sales_item& s){
    double price;
    in >> s.isbn >> s.units_sold >> price;

    if(in)
        s.revenue = s.units_sold * price;
    else
        s = Sales_item();

    return in;
}

int main(){

    Sales_item item(string("0-201-78345-X"), 2, 25.00);

    cout << item << endl;
    cin >> item;
    cout << item << endl;

    system("pause");
    return 0;
}