简体   繁体   中英

Using RAII with C++ streams and STL containers?

I'm trying to use RAII concepts with an STL container of ofstream objects. For example:

int main(int argc, char**argv)
{
  std::deque<std::ofstream> sList;

  sList.push_back(std::ofstream()); // tried variations such as *(new ofstream())
  sList[0].open("test1.txt");
  sList[0] << "This is a test";
  sList[0].close();
}

However, no matter how I try to tweak the code and declarations, the compiler always complains. Apparently the copy constructor for std::basic_ios, which lives inside of streams, is private. Are there any easy plian C++/STL solutions to doing this using RAII, or do I need to get some type of smart pointer involved?

Standard library containers store copies of the values, not the values themselves. As such, you will have to use an object that can be copied (a smart pointer in this case).

An alternative would be boost::ptr_vector which acts as a vector of pointers precisely for this kind of situation.

Stream objects cannot be copied, so you can't create containers of them - you will have to use pointers of some sort.

deque <ofstream *> files;
files.push_back( new ofstream );
// and later delete it, or use a smart pointer

In the interest of keeping a file from being written to in multiple places in various parts of the system, streams are noncopyable. A smart pointer is probably the way to go here.

You probably need to get a smart pointer of some sort involved. One of the requirements of containers (at least in C++) is that to put something in a container, it must be copyable -- and streams are not copyable.

FWIW, in C++0x, this will be possible directly -- it allows containers to hold items that are movable but not copyable, and streams will be movable (but still not copyable).

ofstream has RAII baked in. The destructor of ofstream automagically closes the files so you don't need to.

Use

std::vector<boost::shared_ptr<std::ofstream>> 

as your container and all the file handles will be deleted when you drop the vector.

Do not use a container of std::auto_ptr!

Try using boost::ref. It's meant to store references without copying them. http://www.boost.org/doc/libs/1_43_0/doc/html/ref.htm

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