Win句柄的API包装类

时间:2011-04-20 19:44:29

标签: c++ windows winapi raii

为只能通过值传递的句柄编写包装类相对容易。我试图确定封装需要通过地址传递的句柄的最佳方法是什么。

例如,编写 SC_HANDLE 之类的包装器,通过值传递给 QueryServiceConfig()并不困难。可以实现 .GetHandle()之类的成员函数,也可以实现 operator()

问题(至少对我而言)是像 RegOpenKeyEx()这样的API函数,它需要 HKEY 的地址。

我读过载重载算符&通常是一个坏主意。在允许API函数访问的同时,保持封装(或尽可能多的封装)以及特别是资源集合的推荐方法是什么?

1 个答案:

答案 0 :(得分:2)

您始终可以添加另一个间接层,以避免operator&和丑陋AttachDetach的可怕重载,并从那里返回预先包装的实例。

如果您可以在VS2010或gcc中使用C ++ 0x,或者有其他方式访问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()时关闭注册表项。