自定义ostream [英] A custom ostream

查看:118
本文介绍了自定义ostream的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要一些指导或指导,了解如何实现自定义ostream。我的要求是:

I need some guidance or pointers understanding how to implement a custom ostream. My requirements are:


  1. 一种类型,具有多个数据类型的<<'运算符。

  2. 目的是将输出发送到数据库。

  3. 每个记录最重要的字段将是文本(或blob),但是一些其他字段(如时间等)可以大部分推导出来自动

  4. 缓冲很重要,因为我不想为每个记录都去数据库。

  1. A class with a '<<' operator for several data types.
  2. The intention is to send output to database. Each "line" should go to a separate record.
  3. Each record most important field would be the text (or blob), but some other fields such as time, etc. can be mostly deduced automatically
  4. buffering is important, as I don't want to go to database for every record.



首先,它是否值得从ostream派生?我从ostream得到什么?如果我的类只是实现少量运算符<< 方法(包括一些自定义数据类型)。我从ostream获得了哪些功能?

First, does it worth deriving from ostream? What do I get by deriving from ostream? What if my class simply implements few operator<< methods (including some custom data types). Which functionality do I get from ostream?

假设我想要的是从ostream派生的类,我需要一些指导来了解ostream和streambuf类之间的关系。我需要实现哪一个?看一些样本,似乎我不需要从ostream得到所有,只是给ostream构造函数一个自定义streambuf。真的吗?是规范方法?

Assuming what I want is a class derived from ostream, I need some guidance understanding the relationship between the ostream and the streambuf classes. Which one do I need to implement? Looking at some samples, it appears that I don't need to derive from ostream at all, and just give the ostream constructor a custom streambuf. Is that true? is that the canonical approach?

我需要在自定义streambuf中实现哪些虚拟函数?我看到一些示例(包括此网站:此处这里,以及更多),一些覆盖 sync 方法,其他覆盖 overflow 方法。我应该覆盖哪一个?另外,看一下stringbuf和filebuf源码(Visual Studio或GCC),这两个缓冲类都实现了streambuf的许多方法。

Which virtual functions at the custom streambuf do i need to implement? I've seen some samples (including this site: here and here, and few more), some override the sync method, and other override the overflow method. Which one should I override? Also, looking at the stringbuf and filebuf sources (Visual Studio or GCC) both those buffer classes implement many methods of the streambuf.

如果需要从streambuf派生的自定义类,是否会从stringbuf(或任何其他类)而不是直接从streambuf中获得任何好处?

If a custom class derived from streambuf is required, would there be any benefit deriving from stringbuf (or any other class) instead of directly from streambuf?

至于lines。我希望至少当我的类的用户使用'endl'操纵器是一个新的行(即在数据库中的记录)。也许 - 取决于努力 - 每个'\\\
'字符也应该被视为一个新的记录。

As for "lines". I would like at least when my users of the class using the 'endl' manipulator to be a new line (i.e. record in database). Maybe - depends on effort - every '\n' character should be considered as a new record as well. Who do my custom ostream and/or streambuf get notified for each?

推荐答案

感谢@zaufi,@Nim和@Bart 。我很遗憾地发布了我自己的回答,因为上面的答案都不完整或不容易。

Thank you @zaufi, @Nim, and @Bart. I am (regrettably) going to post my own answer, as none of the answers above are complete or easy.

正如人们指出的,ostream的自定义目的地意味着实现你自己的ostreambuf。如果你想要你的streambuf实际缓冲(即每个字符后不连接到数据库),最简单的方法是创建一个继承自 std :: stringbuf 。您将需要覆盖的 only 函数是 sync()方法,每当流刷新时被调用。

As people pointed out, a custom destination for ostream means implementing your own ostreambuf. If you want your streambuf to actually buffer (i.e. don't connect to the database after each character), the easiest way to do that is by creating a class inheriting from std::stringbuf. The only function that you'll need to override is the sync() method, which is being called whenever the stream is flushed.

class MyBuf : public std::stringbuf
{
public:
    virtual int sync() {
        // add this->str() to database here
        // (optionally clear buffer afterwards)
    }
};

然后,您可以创建 std :: ostream 使用您的缓冲区:

You can then create a std::ostream using your buffer:

MyBuf buff;
std::ostream stream(&buf)

大多数人不建议重新导向到数据库,但他们忽略了我的描述,数据库基本上有一个blob字段,所有的文本将去。
在极少数情况下,我可能会将数据发送到其他字段。这可以通过我的流理解的自定义属性来实现。例如:

Most people advised against redirecting the stream to a database, but they ignored my description that the database basically has a single blob field where all text is going to. In rare cases, I might send data to a different field. This can be facilitated with custom attributes understood by my stream. For example:

MyStream << "Some text " << process_id(1234) << "more text" << std::flush

上面的代码将在数据库中创建一个记录:

The code above will create a record in the database with:

blob: 'Some text more text'
process_id: 1234

process_id()是返回结构 ProcessID 的方法。然后,在我的ostream的实现中,我有一个运算符<<(ProcessID const& pid),它存储进程ID,直到它被写入。工作太棒了!

process_id() is a method returning a structure ProcessID. Then, in the implementation of my ostream, I have an operator<<(ProcessID const& pid), which stores the process ID until it gets written. Works great!

这篇关于自定义ostream的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆