使用 std::ostream 作为 class 成员
Using std::ostream as a class member
我正在开发一个简单的进度指示器 class,我对使用 std::ostream
对象作为 class 成员有疑问。以下示例在 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()
hack。有没有 "better" 更惯用的方法来做到这一点?
您仍在复制 std::ostream
。即使构造函数没有复制参数,它仍然需要以某种方式将对象复制到 ProgressIndicator::stream
。
解决您的问题的一种方法是存储对流的引用,尽管这仅在您知道流对象将比您的 class 实例更持久时才有效:
struct ProgressIndicator {
ProgressIndicator(std::ostream& outstream = std::cerr /* ... */)
: stream(outstream) /* ... */ {}
// ...
protected:
std::ostream& stream;
// ...
};
我正在开发一个简单的进度指示器 class,我对使用 std::ostream
对象作为 class 成员有疑问。以下示例在 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()
hack。有没有 "better" 更惯用的方法来做到这一点?
您仍在复制 std::ostream
。即使构造函数没有复制参数,它仍然需要以某种方式将对象复制到 ProgressIndicator::stream
。
解决您的问题的一种方法是存储对流的引用,尽管这仅在您知道流对象将比您的 class 实例更持久时才有效:
struct ProgressIndicator {
ProgressIndicator(std::ostream& outstream = std::cerr /* ... */)
: stream(outstream) /* ... */ {}
// ...
protected:
std::ostream& stream;
// ...
};