我正在处理一个简单的进度指示器类,我有一个关于使用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;更为惯用的方法呢?
答案 0 :(得分:3)
您仍在复制std::ostream
。即使构造函数没有复制参数,它仍然需要以某种方式将对象复制到ProgressIndicator::stream
。
解决问题的一种方法是存储对流的引用,但这仅在您知道流对象将比您的类实例更久时才有效:
struct ProgressIndicator {
ProgressIndicator(std::ostream& outstream = std::cerr /* ... */)
: stream(outstream) /* ... */ {}
// ...
protected:
std::ostream& stream;
// ...
};