HANDLE
を使用するすべての関数が を使用するわけではなく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(...));
等。