Handles have proper semantics other than pointers. So for me an example like this (extracted from the Rule of Zero):
class module {
public:
explicit module(std::wstring const& name)
: handle { ::LoadLibrary(name.c_str()), &::FreeLibrary } {}
// other module related functions go here
private:
using module_handle = std::unique_ptr<void, decltype(&::FreeLibrary)>;
module_handle handle;
};
using unique_ptr
as an 'ownership-in-a-package' for handles is a bad example. First, it makes use of internal knowledge that the handle is a pointer type, and use this to make a unique_ptr
to the basic type the "opaque" handle type builds upon.
Handles can be any type, they may be a pointer, they may be an index or who knows. Most importantly, what you have at hand (from most C API's for example) is a handle and its resource releasing function.
Is there a proper 'ownership-in-a-package' that works in handle semantics? I mean, already publicly available for one to use?
For me, unique_ptr
et. al. doesn't work, I must make unnecessary assumptions about what the handle type is, when what I want is just to get an 'ownership-in-a-package' through the opaque handle type and its releasing function, solely.
It doesn't make sense for one to peer inside the handle type to make constructions upon this information. It's a handle, it should not matter.
I'll quote here the feelings of another SO user in another question's answer:
Create a specific "smart pointer" class, won't take long. Don't abuse library classes. Handle semantics is quite different from that of a C++ pointer; for one thing, dereferencing a HANDLE makes no sense.
One more reason to use a custom smart handle class - NULL does not always mean an empty handle. Sometimes it's INVALID_HANDLE_VALUE, which is not the same.
Disclaimer:
This question reformulates and builds upon this one:
See Question&Answers more detail:os