使用std :: ostream作为类成员

时间:2016-07-21 13:54:06

标签: c++ ostream

我正在处理一个简单的进度指示器类,我有一个关于使用std::ostream对象作为类成员的问题。以下示例在OS X和Linux上正确编译和运行。

#include <iostream>
#include <string>

struct ProgressIndicator {

public:
    ProgressIndicator(unsigned int update_interval, std::string message,
                      std::ostream& outstream = std::cerr)
        : update_interval(update_interval), message(message),
          stream(outstream.rdbuf()), _counter(0), _interval(update_interval)
    {
    }

    void increment(unsigned int by = 1)
    {
        _counter += by;
        if(_counter >= _interval) {
            stream << message << _counter << std::endl;
            _interval += update_interval;
        }
    }

    unsigned int get_count()
    {
        return _counter;
    }

protected:
    unsigned int update_interval;
    std::string message;
    std::ostream stream;

private:
    unsigned long _counter;
    unsigned long _interval;

};

int main()
{
    ProgressIndicator p1(5, "progress <stdout> ", std::cout);
    for(int i = 0; i < 15; i++) {
        p1.increment();
    }

    ProgressIndicator p2(5, "progress <stderr> ", std::cerr);
    for(int i = 0; i < 15; i++) {
        p2.increment();
    }
    return 0;
}

我知道std::ostream个对象无法复制,必须通过引用传递。但是我不明白为什么用stream(outstream)进行初始化不起作用,以及为什么我不得不诉诸rdbuf()黑客。是否有更好的&#34;更为惯用的方法呢?

1 个答案:

答案 0 :(得分:3)

您仍在复制std::ostream。即使构造函数没有复制参数,它仍然需要以某种方式将对象复制到ProgressIndicator::stream

解决问题的一种方法是存储对流的引用,但这仅在您知道流对象将比您的类实例更久时才有效:

struct ProgressIndicator {
    ProgressIndicator(std::ostream& outstream = std::cerr /* ... */)
      : stream(outstream) /* ... */ {}
    // ...

protected:
    std::ostream& stream;
    // ...
};