Win API классы-оболочки для дескрипторов - PullRequest
7 голосов
/ 20 апреля 2011

Написание класса-оболочки для дескриптора, который передается только по значению, относительно прост. Я пытаюсь определить, как лучше всего инкапсулировать дескрипторы, которые необходимо передать по адресу.

Например, написать оболочку для чего-то вроде SC_HANDLE , который передается по значению в QueryServiceConfig () , не так уж сложно. Можно реализовать функцию-член, например .GetHandle () , или реализовать оператор () .

.

Проблема (по крайней мере для меня) заключается в том, что функции API, такие как RegOpenKeyEx () , для которых требуется адрес HKEY .

Я читал этот оператор перегрузки и вообще плохая идея. Каков рекомендуемый способ сохранить инкапсуляцию (или как можно большую ее часть) и особенно сбор ресурсов при одновременном доступе к функциям API?

1 Ответ

2 голосов
/ 21 апреля 2011

Вы всегда можете добавить еще один слой косвенности, чтобы избежать ужасной перегрузки operator& и уродливых Attach или Detach и вернуть оттуда предварительно упакованный экземпляр.

Если вы можете использовать C ++ 0x в VS2010 или gcc или иметь другие способы доступа к std::unique_ptr<>, то вы можете сделать это (проверка краткости не указана):

struct hkey_deleter
{
    void operator()(HKEY hkey)
    {
        ::RegCloseKey(hkey);
    }
};

typedef std::unique_ptr<HKEY__, hkey_deleter> regkey;

regkey MyRegOpenKeyEx(HKEY hKey, LPCTSTR lpSubKey, DWORD ulOptions, REGSAM samDesired)
{
    HKEY hOpenedKey = NULL;
    ::RegOpenKeyEx(hKey, lpSubKey, ulOptions, samDesired, &hOpenedKey);

    return regkey(hOpenedKey);
}

void SomewhereElse()
{
    ...
    regkey r = MyRegOpenKeyEx(HKEY_CLASSES_ROOT, nullptr, 0, KEY_READ);
    ...
}

hkey_deleter гарантирует, что раздел реестра будет закрыт при выходе из области или при вызове regkey::reset().

...