Использование RAII с потоками C ++ и контейнерами STL? - PullRequest
2 голосов
/ 29 июля 2010

Я пытаюсь использовать RAII концепции с контейнером STL объектов ofstream.Например:

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, или мне нужно задействовать какой-нибудь интеллектуальный указатель?

Ответы [ 6 ]

5 голосов
/ 29 июля 2010

В стандартных контейнерах библиотеки хранятся копии значений, а не сами значения.Таким образом, вам придется использовать объект, который можно скопировать (в данном случае, умный указатель).

Альтернативой будет boost::ptr_vector, который действует как вектор указателей именно для такой ситуации.

4 голосов
/ 29 июля 2010

Потоковые объекты не могут быть скопированы, поэтому вы не можете создавать их контейнеры - вам придется использовать какие-то указатели.

deque <ofstream *> files;
files.push_back( new ofstream );
// and later delete it, or use a smart pointer
3 голосов
/ 29 июля 2010

Возможно, вам понадобится какой-нибудь умный указатель. Одно из требований к контейнерам (по крайней мере, в C ++) заключается в том, что чтобы поместить что-либо в контейнер, оно должно быть копируемым - и потоки не копируемые.

FWIW, в C ++ 0x это будет возможно напрямую - это позволяет контейнерам хранить элементы, которые являются подвижными, но не копируемыми, а потоки будут подвижными (но все же не копируемыми).

3 голосов
/ 29 июля 2010

В целях предотвращения записи файла в нескольких местах в разных частях системы потоки не копируются. Умный указатель - вероятно, путь сюда.

2 голосов
/ 29 июля 2010

ofstream запустил RAII. Деструктор ofstream автоматически закрывает файлы, поэтому вам не нужно.

Используйте

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

в качестве контейнера, и все дескрипторы файлов будут удалены при удалении вектора.

Не используйте контейнер std :: auto_ptr!

0 голосов
/ 29 июля 2010

Попробуйте использовать boost :: ref.Он предназначен для хранения ссылок без их копирования.http://www.boost.org/doc/libs/1_43_0/doc/html/ref.htm

...