1

我有一个派生自 std::ostream 的类(用于日志记录)。剥离下来,它看起来像这样:

class bsgs : public std::ostream {
public:

  bsgs(const std::string& msg = "") {
    // some setup work
  }

  ~bsgs() {
    // some cleanup work
  }

  template<typename T>
  bsgs& operator<<(const T& rhs) {
    os << rhs;
    return *this;
  }

private:
  std::ostringstream os;
};

我编写这个类是为了做一些我需要的特定事情,比如增量压缩。不幸的是,它不起作用。我需要将它传递给提供“set_out”函数以将其输出定向到 std::ostream 的第三方库(带有源代码,但相当大且混乱)。set_out 函数原型正是这样的:

void set_out(std::ostream *out=0, int level=1);

如果我称之为:

set_out(&std::cout, 3);

或者

set_out(&std::cerr, 5);

我得到了完全预期的行为。但是,如果我写:

bsgs logger;
set_out(&logger, 3);

我可以看到记录器的构造函数和析构函数按预期调用但从operator<<未被调用。我不知道为什么,我希望这是一个简单的问题。如果我能解决这个问题,我就准备好了。

有谁知道到底发生了什么?问题似乎是库不知道我传递的是指向 absgs而不是 a的指针std::ostream,但是修复库以接受更广泛的对象,而不仅仅是std::ostream *看起来可能涉及 500 多行代码,其中我想避免。

~~~~~~~~~~~~~~

编辑#1:我不确定它是否重要,但该库set_out() = 0;在其类层次结构的顶部有一个虚函数,它在不同的子类中实现(相同,据我所知)。如果正在编写库,我会创建set_out一个(非虚拟)模板函数并提供 std::ostream 的专门化,但让用户提供他们喜欢的任何内容,只要他们定义一个可用的operator<<. 对库进行此更改看起来将是整整半天的编辑。也许有更简单的方法?

4

2 回答 2

1

该库不知道您正在传递指向 a 的指针-bsgs您没有覆盖虚函数,不涉及多态性。

您可能会发现实现streambuf和替换与流关联的流缓冲区 ( ostream::rdbuf) 是一种更可行的解决方案。

于 2011-03-13T12:50:13.977 回答
1

您可以随时使用

std::ostringstream os;
set_out(&os, 3);

当您想从 ostream 派生时,只需创建自己的streambuf实现,它是虚拟的,并创建类似的流

std::ostream stream(new myStreamBuf);
set_out(&stream, 3);
于 2011-03-13T12:55:40.563 回答