重载输入输出运算符

重载输入输出运算符

我们平时可以用流 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. 下面是一个例子:
#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. 输入运算符必须处理输入可能失败的情况,而输出运算符不需要。
输入时会发生的错误

可能会发生下列错误:
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;
}


  • 4
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值