zoukankan      html  css  js  c++  java
  • 解读C++重载ostream与istream

    C++中,我们可以重载输入输出流操作符<<与>>来自定义其输入输出功能。

    class Foo
    {
    public:
        Foo() :high(0), wide(0){}
        Foo(int a, int b) :high(a), wide(b){}
    
        Foo & operator++();//前置
        const Foo operator++(int);//后置调用前置
    
        friend const ostream& operator<< (const ostream&,const Foo&);
        //这样写 流对象之前加const常量限制符,会报错
    private:
        int high;
        int wide;
    };
    
    const ostream& operator<< (const ostream& os, const Foo& foo)
    {
        os << foo.high << " " << foo.wide;
        return os;
    }

    上面的写法 在流对象之前使用 const ,编译器会报错,报错提示如下:

    image

    错误提示原因是 输入流对象 没有匹配的 常量类型 输出。说白了就是 输出流操作 不能在输出 一个数据流而其本身没有任何变化。(如果理解不了这句话,可以先跳过,往后继续看,相信看完之后再来看这句话,就能理解了)

    下面来试试去掉const常量修饰符之后的结果:

    class Foo
    {
    public:
        Foo() :high(0), wide(0){}
        Foo(int a, int b) :high(a), wide(b){}
    
        Foo & operator++();//前置
        const Foo operator++(int);//后置调用前置
    
        friend ostream& operator<< (ostream&,const Foo&);
        //这是去掉const常量修饰符,正确的做法
    
    private:
        int high;
        int wide;
    };
    
    ostream& operator<< (ostream& os, const Foo& foo)
    {
        os << foo.high << " " << foo.wide;
        return os;
    }

    编译通过,没有报错。

    为什么加上const 修饰符之后,就是错误的呢?const 是用来修饰不会改变的 对象或变量状态的常量修饰符。而此处不能在重载的流对象之前加 const 说明 Foo类的友元函数 输出流对象 之后改变了流对象本身的状态。

    C++ primer 对此的描述是“读写IO对象会改变其状态,返回的引用不能是const“。

    那么一个流对象,使用之后,其状态为什么被改变了呢?

    我们先来想一下我们处理一个文本文件的场景:先打开一个文本文件,获得其句柄,通过该句柄可以对其读写操作(注意此处的读写操作,很像我们的流操作。其实C++的文件操作,标准化就是通过重载<<与>>进行流读写的)。文件读写通过两个文件指针,一个读指针,一个写指针,每次进行读或写操作,读写指针就会自动往后移动。注意这里,读写指针自动移动。这里就已经改变了文件的流对象 的状态。

    同理,我们的屏幕输出流对象和键盘输入流对象,也有这么类似的一对自动移动的读写指针,每次进行流操作时,例如在屏幕打印一个字符,屏幕输出流对象的位置指针就会向后移动一个单位。这里就改变了流对象的状态。

    下面引用一位网友对此形象的描述:河里的水流虽然看起来没有变化,但是有水流过,肯定有东西发生了变化(河床发生了侵蚀,沙子发生了沉积)。

  • 相关阅读:
    [知乎作答]·关于在Keras中多标签分类器训练准确率问题
    [深度应用]·Keras极简实现Attention结构
    工作队列work queues 公平分发(fair dispatch) And 消息应答与消息持久化
    RabbitMQ 之 WorkQueues工作队列
    RabbitMQ初体验
    RabbitMQ 简单了解以及使用
    画龙点睛 之RabbitMQ 初来乍到
    JVM 深入浅出
    HashMap和ConcurrentHashMap和HashTable的底层原理与剖析
    Lucene
  • 原文地址:https://www.cnblogs.com/wangzhizhen/p/7828750.html
Copyright © 2011-2022 走看看