zoukankan      html  css  js  c++  java
  • C++ 流插入"<<"和流提取">>"运算符的重载

    微信公众号:「小林coding」
    用简洁的方式,分享编程小知识。

    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,20,小林coding
    

    需要注意是 ostream & operator<<(ostream & o, const CStudent & s) 函数是全局的,所以函数的第一个参数必须要传入 ostream 的对象,并且 CStudent 类需要将此函数声明成友元函数,使得函数可以访问 CStudent 类的私有成员变量。

    03 流提取>>运算符重载的例子

    还是以 CStudent 类作为例子,假设想通过键盘的输入的内容,来初始化对象,则我们可以重载 istream 类的流提取 >> 运算符。

    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);
        
        // 将该函数声明成友元函数
        // 目的是使得函数可以给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, const CStudent & s)
    {
        o << s.m_id << "," << s.m_age << "," << 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,20,小林coding
    
    // 输出内容:
    1,20,小林coding
    

    04 小结

    要想流插入 << 运算符和流提取 >> 运算符能针对自定义的对象,那么我们就需要重载针对该对象的 ostream 类的 << 运算符 和 istream>> 运算符,并且只能重载成全局的函数,然后在 CStudent 类里需要把上面的两个重载函数声明成友元函数,使得两个重载的函数可以访问和赋值 CStudent 类里的私有成员函数。


  • 相关阅读:
    2018.7.12训练赛 -K
    winter 2018 02 01 关于模运算的一道题
    debug(实验)
    problem-1003(恢复一下)
    hd acm1466
    hd acm2045
    hd acm 1297
    hd acm1005
    hd acm1425
    概率趣题:三个犯人
  • 原文地址:https://www.cnblogs.com/xiaolincoding/p/11969861.html
Copyright © 2011-2022 走看看