简体   繁体   English

派生std :: ofstream和重载运算符<

[英]Deriving std::ofstream and overloading operator<<

How to derive from the std::ofstream class, to add a few actions before writing to a file? 如何从std :: ofstream类派生,在写入文件之前添加一些操作? In other words, replacing code like 换句话说,替换如下代码

int main()
{
   std::ofstream file("file.txt");
   file << "something" << std::endl;
   return 0;
}

by 通过

class MyFile : public std::ofstream
{
   MyFile(std::string filename) : std::ofstream(filename) {}

   ??? operator<< ???   <-- HERE1
   {
      // 1. do some stuff with the input
      // 2. if wanted,
      // flush it to the base class operator<<
   }
};

class MyFileC
{
private:
   std::ofstream intern_os;
public:
   MyFileC(std::string filename) : intern_os(filename) {}

   MyFileC& operator<<( input ???   <-- HERE2  )
   {


          // 1. do some stuff with the input
          // e.g (a) IF the input is a std::string,
          // THEN, if it contains "signal",
          // OnSignal();
          // or (b) if file size is too big, clear it ...
          // 2. Flush it (for all possible types):

      intern_os << input;
   }
};

int main()
{
    MyFile file("file2.txt"); // (or with MyFileC)
    file << "something" << std::endl;
    return 0;
}

where we could for example filter on-the-fly before writing etc. 在这里我们可以例如在编写之前进行动态过滤等。

What to put in the ??? 放什么??? lines to enjoy all the existing std::ofstream.operator<<(), with our personal addings, please? 可以享受我们现有的所有std :: ofstream.operator <<()以及我们的个人添加内容吗?

  • HERE1 : more elegant, with inheritance approach; HERE1 :更优雅,采用继承方法; or if impossible (after the comments below), 或者,如果不可能(在下面的评论之后),
  • HERE2 : what type to give to pass "whatever that could passed to the internal std::ofstream" (strings, ints, ...) HERE2 :要传递的类型是“传递给内部std :: ofstream的所有东西”(字符串,整数,...)

operator<< isn't intended to be overwritten by derived stream classes. operator<<不能被派生的流类覆盖。 Instead, you should override std::basic_streambuf::overflow and/or std::basic_streambuf::xsputn . 相反,您应该重写std::basic_streambuf::overflow和/或std::basic_streambuf::xsputn

overflow in particular is called internally whenever the buffer overflows. overflow每当缓冲器溢出,特别在内部调用。 If you want to provide your own buffering, you can do this by initialising the stream pointers via std::basic_streambuf::setp inside your overridden stream class. 如果要提供自己的缓冲,则可以通过重写的流类内的std::basic_streambuf::setp初始化流指针来实现。 The links come with examples of how to do that. 这些链接附带了如何执行此操作的示例。

There's just one cosmetic problem here: these are all buffer methods. 这里只有一个修饰问题:这些都是缓冲方法。 You want to override std::fstream , which is a stream class, not a buffer class . 您想覆盖std::fstream ,它是一个类,而不是一个缓冲区 What you need to do is therefore twofold: 因此,您需要做的是双重的:

  1. Override std::basic_filebuf as described above. 如上所述覆盖std::basic_filebuf
  2. Use std::fstream::rdbuf to set the associated buffer of a file stream object to an instance of your overridden file buffer class. 使用std::fstream::rdbuf可以将文件流对象的关联缓冲区设置为覆盖的文件缓冲区类的实例。 You can do this either on an instance of the existing std::fstream or on a custom subclass of that type. 您可以在现有std::fstream的实例上或在该类型的自定义子类上执行此操作。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM