自己的输出流(mock-cout)

Own output stream (mock cout)

本文关键字:mock-cout 输出流 自己的      更新时间:2023-10-16

这是一个示例C++代码

ostream& log = cout;
ostream& getLog() { return log; }
// somewhere in code
getLog() << "Message";

当执行此代码时,将打印"消息"。

Q:丢弃这些消息的最简单方法是什么(不要打印,也不要保存)?客户端必须仍然使用getLog,但可能会返回一些包含所有消息的模拟输出流。。。

你可以做以下可怕的事情:

ostream nullstream(0);
ostream& log = nullstream;

将null传递给ostream的构造函数将设置badbit标志,从而放弃所有写入。

有一篇类似的文章试图做到这一点-模拟重定向到/dev/null 的cpp方法

实现一个容易吗?

是的。从std::streambuf派生一个类,并覆盖受保护的虚拟函数溢出如下

int溢出(int c){return c;}

然后,您可以使用标准istream并将其流缓冲区设置为使用rdbuf的streambuf类的实例。或者您可以定义自己派生的ostream类,该类自动使用你的streambuf课程。

快速脏:

定义一个从std::ostream派生的类,该类为不做任何事情的T实现<<运算符。

不幸的是,这在某些情况下可能不起作用:std::ostream中的<<运算符不是多态的(不是虚拟的),因此只有当流类型是yourstream&而不是std::ostream&时,才会调用重写的<<

更礼貌

派生std::streambuf,该类没有缓冲区,并且通过覆盖overflow总是返回0

然后创建一个与该缓冲区相关联的std::ostream,并从getLog()返回它;

这将使ostream发挥其作用:将值转换为文本并将字符发送到缓冲区。缓冲区什么都不做就把它们吃掉了。

对于库来说,礼貌是不那么有效的,因为ostream值在任何情况下都会调用文本例程。

最高效

是使日志记录语句的编译符合条件:如

#ifdef DEBUG
#define DBG(x) x
#else
#define DBG(x)
#endif
// Your entire code here
#undef DBG

并将日志记录写入

DBG(std::cout << logging_variables_and_text << std::endl);

当未定义DEBUG时,DBG中的所有内容都将被擦除(不再花费CPU周期)