2010-07-29 6 views
2

Я пытаюсь использовать RAII концепции с контейнером STL из объектов. Например:Использование RAII с потоками C++ и 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, или мне нужно использовать какой-либо тип умного указателя?

ответ

3

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

+0

Хотя все ответы здесь имеют хорошую информацию, мне понравился ваш ответ, потому что он объясняет логическое обоснование того, что поток файлов не копируется. Отлично сработано! –

4

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

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

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

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

3

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

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

+0

Интересный момент о C++ 11, который, ускоренный переход на 3 года, стал актуальным. –

0

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

+0

И где хранить фактические потоки? –

+0

Где вы их создаете. { std :: поток потока; { std :: deque > sList; sList.push_back (boost: ref (поток)); ... } // Поток уничтожен. } – Scharron

+0

И как это помогает аферу? –

2

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

Использование

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

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

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

+0

Да, я слышал не очень-то хорошие вещи о std :: auto_ptr. :-) –

+0

Нет ничего плохого в std :: auto_ptr. Просто не используйте его для вещей, для которых он не предназначен для использования. auto_ptr перемещает содержащийся указатель на копию. Так что если у вас есть. http://gist.github.com/498683 Когда p выходит из области действия, он удаляет объект foo. – bradgonesurfing

+0

Нет ничего плохого в auto_ptr. Он имеет конкретный прецедент, и вам просто нужно знать подходящее время и место, где его использовать. –