简体   繁体   中英

Deriving std::ofstream and overloading operator<<

How to derive from the std::ofstream class, to add a few actions before writing to a file? 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?

  • HERE1 : more elegant, with inheritance approach; 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, ...)

operator<< isn't intended to be overwritten by derived stream classes. Instead, you should override std::basic_streambuf::overflow and/or std::basic_streambuf::xsputn .

overflow in particular is called internally whenever the buffer overflows. 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. 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 . What you need to do is therefore twofold:

  1. Override std::basic_filebuf as described above.
  2. Use std::fstream::rdbuf to set the associated buffer of a file stream object to an instance of your overridden file buffer class. You can do this either on an instance of the existing std::fstream or on a custom subclass of that type.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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