【问题标题】:Using RAII with C++ streams and STL containers?将 RAII 与 C++ 流和 STL 容器一起使用?
【发布时间】:2011-03-22 19:23:12
【问题描述】:

我正在尝试将RAII 概念与 ofstream 对象的 STL 容器一起使用。例如:

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();
}

但是,无论我如何尝试调整代码和声明,编译器总是会报错。显然,位于流内部的 std::basic_ios 的复制构造函数是私有的。是否有任何简单的 C++/STL 解决方案可以使用 RAII 执行此操作,或者我是否需要涉及某种类型的智能指针?

【问题讨论】:

    标签: c++ stl raii iostream


    【解决方案1】:

    标准库容器存储值的副本,而不是值本身。因此,您必须使用可复制的对象(在本例中为智能指针)。

    另一种选择是boost::ptr_vector,它正好充当这种情况下的指针向量。

    【讨论】:

      【解决方案2】:

      流对象不能被复制,所以你不能为它们创建容器——你必须使用某种指针。

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

      【讨论】:

        【解决方案3】:

        为了防止文件被写入系统各个部分的多个位置,流是不可复制的。智能指针可能是这里的方法。

        【讨论】:

        • 虽然这里的所有答案都有很好的信息,但我喜欢你的答案,因为它解释了为什么文件流不可复制的理由。干得好!
        【解决方案4】:

        您可能需要使用某种类型的智能指针。容器的要求之一(至少在 C++ 中)是要将某些东西放入容器中,它必须是可复制的——而流不可可复制。

        FWIW,在 C++0x 中,这将直接成为可能——它允许容器保存可移动但不可复制的项目,并且流将是可移动的(但仍不可复制)。

        【讨论】:

        • 关于 C++11 的有趣点,快进 3 年多,现在已经变得相关了。
        【解决方案5】:

        ofstream 包含 RAII。ofstream 的析构函数会自动关闭文件,因此您不需要这样做。

        使用

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

        因为你的容器和所有文件句柄都会在你删除向量时被删除。

        不要使用 std::auto_ptr 的容器!

        【讨论】:

        • std::auto_ptr 没有问题。只是不要将它用于不应该用于的事情。 auto_ptr 在副本上移动包含的指针。所以如果你有。 gist.github.com/498683 当 p 超出范围时,它会删除对象 foo。
        • auto_ptr 没有问题。它有特定的用例,您只需要知道使用它的适当时间和地点。
        • 我应该对我的陈述进行限定。由于很多 STL(包括容器)会复制正在使用的对象,因此 auto_ptr 不适合这种情况,因为没有两个 auto_ptr 应该拥有相同的元素。
        【解决方案6】:

        尝试使用 boost::ref。它旨在存储引用而不复制它们。 http://www.boost.org/doc/libs/1_43_0/doc/html/ref.htm

        【讨论】:

        • 在哪里存储实际流?
        • 创建它们的位置。 { std::ofstream 流; { std::deque<:ref>> sList; sList.push_back(boost:ref(stream)); ... } // 流被销毁。 }
        • 它对提问者有什么帮助?
        • 不需要复制构造函数,这是问题所在。
        • 没关系(实际上有点挑战性,因为它的答案太老了,我不记得回答了)。也有一个愉快的周末:-)
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-03-16
        • 2011-01-08
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多