C++ 中的自定义流到方法?
我正在制作一个记录器,我希望发生某种类似流的事件,最好是 CLogger << “测试”<< 1<<; ",2,3\n";
而不是 CLogger->log("Testing, %i,2,3", 1);
我的问题是我该怎么做?我不想直接创建到标准输出的流,因为我想使用我自己的方法,其中包括写入文件等。我考虑过使用某个结构进行重载,将当前流缓冲区刷新到方法,但我必须执行 CLogger <<冲洗<< “测试!\n”; 这有点奇怪。
有人知道该怎么做吗?
I'm making a logger and I wish to have some kind of stream-like happenings going on, ideally doing CLogger << "Testing, " << 1 << ",2,3\n";
instead of CLogger->log("Testing, %i,2,3", 1);
My question is how would I do this? I don't want to directly create a stream to stdout as I want to use my own method which includes writing files and such. I've considered overloading with a certain struct that'd flush the current stream buffer to a method, but I'd have to do CLogger << flush << "Test!\n";
which is kind of odd.
Does anybody know how to do this?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
如果您需要的只是将某些日志消息定向到文件,您是否考虑过 std::ofstream?
否则,我喜欢从
std::ostream
派生我的日志记录类,这样我就可以获得所有流的优点。诀窍是将所有特定于应用程序的代码放入关联的streambuf 类中。考虑:注意:
If all that you need is directing certain log messages to files, have you considered
std::ofstream
?Otherwise, I like to derive my logging class from
std::ostream
, so I get all of the stream goodness. The trick is to put all of your application-specific code in the associated streambuf class. Consider:Notes:
查看
运算符<<
,它是STL 的流重载的内容。编辑:
请参阅此页面,概述了 std::ostream 如何重载不同类型的运算符 <<:
http://www.cplusplus.com/reference/iostream/ostream/operator%3C%3C/
Check out
operator <<
, which is what STL's streams overload.EDIT:
See this page that outlines how std::ostream overloads
operator <<
for different types:http://www.cplusplus.com/reference/iostream/ostream/operator%3C%3C/
实现一个代理对象,为您提供运算符<<并将所有权标记传递给返回的代理对象。当带有所有权标记的对象死亡时,您将刷新流。
执行此操作的一个简单方法是将 ostringstream 包装在代理中的 auto_ptr 中,并在代理的 d-tor 中 auto_ptr 不为 null 时刷新到记录器。
这将为您提供 ostream 可能的格式,但仍然只会导致对记录器的一次调用,我认为这是真正的问题。
想想这样的事情:
Implement a proxy object that gives you operator<< and pass an ownership marker to the returned proxy object. When an object with the ownership marker dies, you flush the stream.
An easy way to do this would be to wrap ostringstream in an auto_ptr in your proxy and flushing to your logger when the auto_ptr is not null in the proxy's d-tor.
That'll give you the formatting possible with ostream, but still result in only one call to your logger, which I thought was the real problem.
Think of something like this:
所有
operator<<()
函数都在类ostream
上定义,您可以继承该类并实现其方法。All of the
operator<<()
functions are defined on the classostream
, which you can inherit from and implement its methods.我将在下面复制粘贴我当前的实现,它可以满足您所需的一切(并处理诸如 std::endl 之类的事情)。 AMBROSIA_DEBUG 是在调试版本中定义的宏,因此理论上,在发布版本中应该省略对此输出类的每次调用(虽然尚未检查,但似乎逻辑开销保持在最低限度。功能基于
QDebug
功能,加上我的debugLevel
功能,它允许您根据运行时参数在代码中手动过滤调试消息。还在每条消息之前添加相同数量的空格。示例用法:
I'm just going to copy-paste my current implementation of this below, it does all you need (and handles things like
std::endl
and the like).AMBROSIA_DEBUG
is macro defined in debug builds, so in theory, every call to this output class should be omitted in release builds (haven't checked though, but seems logical overhead is kept to a minimum. The functionality is based onQDebug
functionality, plus a little addition of minedebugLevel
, which would allow you to filter debug messages by hand in your code depending on a runtime parameter. Right now it also adds the same amount of spaces before each message.Example usage: