c++ - 将 std::ostream 的子级传递给需要 std::ostream * 的库

标签 c++ logging polymorphism ostream

我有一个派生自 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 函数原型(prototype)就是这样:

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<<永远不会被调用。我不确定为什么,我希望这是一个简单的问题。如果我能解决这个问题,我就万事大吉了。

有谁知 Prop 体是怎么回事吗?问题似乎是图书馆不知道我正在传递一个指向 bsgs 的指针。而不是 std::ostream , 但修复库以接受更广泛的对象而不仅仅是 std::ostream *看起来它可能涉及 500 多行代码,我想避免这种情况。

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

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

最佳答案

没有不知道您正在将指针传递给 bsgs - 您没有覆盖虚函数,不涉及多态性。

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

关于c++ - 将 std::ostream 的子级传递给需要 std::ostream * 的库,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5289406/

相关文章:

c++ - 可变函数指针转换

c++ - C++ 中的 C# Dll,如何

c++ - 使用字符串参数创建 SDL_thread

java - Logger.getLogger(className) 和 LogFactory.getLog(className) 之间的区别?

c++ - 如果我只有基类指针,如何使用派生类?

c++ - 为什么会有单独的 "trie_node"和 "trie"结构?

c# - 如何设置 NLog 最大文件大小?

logging - 应用日志聚合、管理和通知

php:数组对象的迭代器实现的多态性?

使用组合映射的 Haskell 多态递归会导致无限类型错误