gpt4 book ai didi

c++ - 使用带有自定义删除器的 shared_ptr 使 HANDLE RAII 兼容

转载 作者:可可西里 更新时间:2023-11-01 15:08:12 25 4
gpt4 key购买 nike

我最近在 SO 上发布了一个关于 RAII 的一般性问题.但是,我的 HANDLE 示例仍然存在一些实现问题。

HANDLEwindows.h 中被定义为 void *。因此,正确的shared_ptr定义需要是

std::tr1::shared_ptr<void> myHandle (INVALID_HANDLE_VALUE, CloseHandle);

示例 1 CreateToolhelp32Snapshot:返回 HANDLE 并运行。

const std::tr1::shared_ptr<void> h
(CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, NULL), CloseHandle);

当我在定义中使用 void(正确的方法是什么?)时,当我尝试使用此指针调用更多 winapi 命令时,问题继续存在。它们在功能上有效,但很丑陋,我相信必须有更好的解决方案。

在下面的示例中,h 是一个指针,它是通过顶部的定义创建的。

示例 2 OpenProcessToken:最后一个参数是 PHANDLE。 Actor 中等丑陋。

OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY,
(PHANDLE)&h);

示例 3 Process32First:第一个参数是 HANDLE。真的很丑。

Process32First(*((PHANDLE)&h), &pEntry);

示例 4 与常量 HANDLE 的简单比较。真的很丑。

if (*((PHANDLE)&h) == INVALID_HANDLE) { /* do something */ }

为 HANDLE 创建合适的 shared_ptr 的正确方法是什么?

最佳答案

例子1可以

示例 2 是错误的。通过盲目地转换为 PHANDLE,绕过了 shared_ptr 逻辑。它应该是这样的:

HANDLE h;
OpenProcessToken(...., &h);
shared_ptr<void> safe_h(h, &::CloseHandle);

或者,分配给预先存在的 shared_ptr:

shared_ptr<void> safe_h = ....
{
HANDLE h;
OpenProcessToken(...., &h);
safe_h.reset(h, &::CloseHandle);
}//For extra safety, limit visibility of the naked handle

或者,创建您自己的、安全的 OpenProcessToken 版本,它返回共享句柄而不是采用 PHANDLE:

// Using SharedHandle defined at the end of this post
SharedHandle OpenProcess(....)
{
HANDLE h = INVALID_HANDLE_VALUE;
::OpenProcessToken(...., &h);
return SharedHandle(h);
}

例子3:不用走这些弯路。这应该没问题:

Process32First(h.get(), ...);

示例 4:同样,不绕路:

if (h.get() == INVALID_HANDLE){...}

为了让事情变得更好,你可以输入类似这样的东西:

typedef shared_ptr<void> SharedHandle;

或者更好的是,如果要使用 CloseHandle() 关闭所有句柄,创建一个 SharedHandle 类包装一个 shared_ptr 并自动提供正确的删除器:

// Warning: Not tested. For illustration purposes only
class SharedHandle
{
public:
explicit SharedHandle(HANDLE h) : m_Handle(h, &::CloseHandle){};
HANDLE get()const{return m_Handle.get();}

//Expose other shared_ptr-like methods as needed
//...

private:
shared_ptr<void> m_Handle;
};

关于c++ - 使用带有自定义删除器的 shared_ptr 使 HANDLE RAII 兼容,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1562421/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com