Я - любитель C++. Я пишу некоторому Win32 код API и существуют дескрипторы и странно сложно выделенные объекты много. Таким образом, я задавался вопросом - там некоторый класс обертки, который сделал бы управление ресурсами легче?
Например, когда я хочу загрузить некоторые данные, я открываю файл с CreateFile()
и получите a HANDLE
. Когда я сделан с ним, я должен звонить CloseHandle()
на нем. Но для любой довольно сложной функции загрузки будут десятки возможных точек выхода, не говоря уже об исключениях.
Таким образом, было бы замечательно, если бы я мог бы перенести дескриптор в некоторый класс обертки, который автоматически звонил бы CloseHandle()
после того как выполнение оставило объем. Еще лучше - это могло сделать некоторый подсчет ссылок, таким образом, я могу раздать его в и из других функций, и это выпустило бы ресурс только, когда последняя ссылка оставила объем.
Понятие просто - но является там чем-то как этот в стандартной библиотеке? Я использую Visual Studio 2008, между прочим, и я не хочу присоединять стороннюю платформу как Повышение или что-то.
Напишите свой собственный. Это всего лишь несколько строк кода. Это настолько простая задача, что не стоит предоставлять универсальную многоразовую версию.
struct FileWrapper {
FileWrapper(...) : h(CreateFile(...)) {}
~FileWrapper() { CloseHandle(h); }
private:
HANDLE h;
};
Подумайте, что должна делать универсальная версия: она должна быть параметризуемой, чтобы вы могли указать любую пару функций и любое количество аргументов для них. Для простого создания экземпляра такого объекта, вероятно, потребуется столько же строк кода, сколько в приведенном выше определении класса.
Конечно, C ++ 0x может несколько склонить чашу весов за счет добавления лямбда-выражений. Два лямбда-выражения можно легко передать в общий класс-оболочку, поэтому, как только появится поддержка C ++ 0x, мы можем увидеть такой общий класс RAII, добавленный в Boost или что-то в этом роде.
Но на данный момент проще просто свернуть свой, когда вам это нужно.
Что касается добавления подсчета ссылок, я бы не советовал этого делать. Подсчет ссылок - дело дорогое (внезапно ваш дескриптор должен быть динамически выделен, а счетчики ссылок должны поддерживаться при каждом назначении), и его очень сложно получить правильно. Это область, просто разорванная тонкими условиями гонки в многопоточной среде.
Если вам требуется подсчет ссылок, просто сделайте что-нибудь вроде boost :: shared_ptr
: заключите свои специальные специальные классы RAII в shared_ptr
.
Вот один, основанный на коде EnsureCleanup из «Windows через C / C ++»: http://www.codeproject.com/KB/cpp/template2003.aspx
Visual C ++ 2008 поддерживает TR1 через Feature Pack, а TR1 включает shared_ptr. Я бы использовал это - это очень мощный класс интеллектуальных указателей, который можно обобщить для выполнения требуемого вами типа управления ресурсами.
TR1 фактически является расширением стандарта. Я считаю, что это все еще официально "предварительный стандарт", но фактически вы можете считать его заблокированным.
Я не думаю, что есть что-то в стандартной библиотеке, и я также сомневаюсь, что общие указатели (как в boost) могут быть использованы (поскольку они будут ожидать указатель на HANDLE, а не HANDLE).
Не должно быть трудно написать его самостоятельно, следуя идиоме scope guard (и используя шаблоны/функциональные указатели и т.д., если вы захотите).
По сути, fstream
- хорошая оболочка C ++ для дескрипторов файлов. Это часть стандарта, что означает, что он переносимый, хорошо протестированный и расширяемый объектно-ориентированным способом. Для файловых ресурсов это отличная концепция.
Однако fstream
работает только для файлов, а не для общих дескрипторов, то есть потоков, процессов, объектов синхронизации, файлов с отображением в память и т. Д.
MFC имеет некоторые подходящие примитивы (посмотрите, например, на CFile), но не стандартную библиотеку.