并非所有使用HANDLE
use的函数CloseHandle()
,有些使用其他关闭函数。此外,并非所有HANDLE
值都使用INVALID_HANDLE_VALUE
。有的NULL
改用。
HBITMAP
从不使用INVALID_HANDLE_VALUE
,它总是使用NULL
。你永远不应该要求DeleteObject()
一个HBITMAP
你不拥有的东西。
所以简短的回答是 - 如果您正在尝试创建一些通用句柄管理,请不要打扰。你很可能会弄错。如果您分配/打开某个句柄,您必须知道关闭它的正确方法,您无法猜测它。
如果您希望手柄自行管理,那么 RAII 是最佳选择。我更喜欢使用具有特殊特征的模板类来减少不同类型句柄的代码重复,例如:
template< class traits >
class HandleWrapper
{
private:
traits::HandleType FHandle;
public:
HandleWrapper()
FHandle(traits::InvalidValue)
{
}
HandleWrapper(const traits::HandleType value)
FHandle(value)
{
}
~HandleWrapper()
{
Close();
}
void Close()
{
if (FHandle != traits::InvalidValue)
{
traits::Close(FHandle);
FHandle = traits::InvalidValue;
}
}
bool operator !() const {
return (FHandle == traits:::InvalidValue);
}
operator bool() const {
return (FHandle != traits:::InvalidValue);
}
operator traits::HandleType() {
return FHandle;
}
};
.
struct KernelHandleTraits
{
typedef HANDLE HandleType;
static const HANDLE InvalidValue = INVALID_HANDLE_VALUE;
static void Close(HANDLE value)
{
CloseHandle(value);
}
};
HandleWrapper<KernelHandleTraits> hFile(CreateFile(...));
.
struct NullKernelHandleTraits
{
typedef HANDLE HandleType;
static const HANDLE InvalidValue = NULL;
static void Close(HANDLE value)
{
CloseHandle(value);
}
};
HandleWrapper<NullKernelHandleTraits> hMapping(CreateFileMapping(...));
.
struct FileMapViewTraits
{
typedef void* HandleType;
static const void* InvalidValue = NULL;
static void Close(void *value)
{
UnmapViewOfFile(value);
}
};
HandleWrapper<FileMapViewTraits> hView(MapViewOfFile(...));
.
struct GDIBitmapHandleTraits
{
typedef HBITMAP HandleType;
static const HBITMAP InvalidValue = NULL;
static void Close(HBITMAP value)
{
DeleteObject(value);
}
};
HandleWrapper<GDIBitmapTraits> hBmp(CreateBitmap(...));
等等。