C++重载istream和ostream

对于一般的运算符重载,可以重载为类的成员函数,这是因为操作符的第一个元素一定是本类的对象(this)

例如

#include<iostream>
using namespace std;

class book {
public:
    book (int n):bookNo(n) {}
    int getBookNo () {
        return bookNo;
    }
    book operator+ (book b) {
        book result(0);
        result.bookNo = bookNo + b.bookNo;
        return result;        
    }
private:
    int bookNo;
};

int main () {
    book a(10), b(20);
    auto res = a + b;
    cout << res.getBookNo();
}

这里重载的 “+”号,是因为我们可以直接去修改对象的值

然而,对于 << >>来说,其左侧必须是istream 或者 ostream的对象,我们没办法去直接改变istream对象的值(不然就得去<iostream>的源代码中修改),所以也就没办法把它写为当前类的成员函数。

解决方法1:

申明为当前类的友元函数,这样就可以直接访问类的私有对象(但是会破坏封装性)

#include<iostream>
using namespace std;

class book {
public:
    int getBookNo () {
        return bookNo;
    }
    friend istream& operator>> (istream& in, book& b);
    friend ostream& operator<< (ostream& out, book b);
private:
    int bookNo;
};

istream& operator>> (istream& in, book& b) {
    in >> b.bookNo;
    return in;
}
ostream& operator<< (ostream& out, book b) {
    out << b.bookNo;
    return out;
}

int main () {
    book b;
    cout << "input book number: ";
    cin >> b;
    // cout << "book number is " << b.getBookNo() << endl;
    cout << b;
}

可以看到声明为book类友元的全局函数operator<< 和 operator >>直接访问了book类的私有变量成员bookNo

解决方法2:

使用一些成员函数来暴露对类成员的访问,然后使用类外的普通函数重载来进行类成员的输入输出。

#include<iostream>
using namespace std;

class book {
public:
    int getBookNo () {
        return bookNo;
    }
    void setBookNo (int n) {
        bookNo = n;
    }
private:
    int bookNo;
};

istream& operator>> (istream& in, book& b) {
    int tmp;
    in >> tmp;
    b.setBookNo(tmp);
    return in;
}
ostream& operator<< (ostream& out, book b) {
    out << b.getBookNo();
    return out;
}

int main () {
    book b;
    cout << "input book num: ";
    cin >> b;
    cout << "book num is " << b;
}

至于为什么这里返回的是引用呢?

这里还没彻底弄明白,如果返回的不是引用,会报如下错误:

也就是当返回值不是引用时,就会调用拷贝构造函数,但是看上图可知道 istream和ostream的拷贝构造都被显示的删掉了!!

那为什么要显示的删掉拷贝构造呢?

是因为要保证输入,输出流对象是同一个对象

比如,cin >> a >> b;

如果返回不是引用,那么cin >> a产生一个istream的对象(开辟一段新空间),又作为 >> b左侧的istream的对象,这两个对象不能保证是同一个对象。可能发生如下情况:

而返回时引用的时候,可以保证,cin >> a >> b >> c都在同一个流对象中

 

  • 12
    点赞
  • 54
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值