Boost logo

Boost :

From: John Madsen (johnmadsen_usenet_at_[hidden])
Date: 2003-07-11 15:12:54


Starting from the smart_ptr headers (shared, scoped, and weak), I've created
corresponding handle classes. The motivation is to provide RAII semantics for
handle based resources. Windows' HANDLEs, FILE*s, and file descriptors are the
most obvious examples.

There are two main differences between the smart_handle and smart_ptr classes.

1) Pointer specific features have been removed for smart_handle. Both
implicit and explicit type coercion features are gone as are operators * and ->.
2) Rather than taking the handle type as a template parameter, smart_handle
classes take a handle policy (or traits class or description class or whatever
the correct term is).

(2) is designed to deal with the fact that the actual type of a handle rarely
uniquely identifies the handle type. Most Windows' handles are actually void
pointers, file descriptors are ints, etc. Because the smart_handle classes
take a handle policy as a template parameter, smart_handles that are logically
distinct types will be properly distinguished by the language's type system.
For example, to define a scoped_handle for a Windows' file HANDLE you'd do the
following:

struct win_file_handle {
    typedef HANDLE handle_type;
    static bool is_valid(handle_type h) { return h != INVALID_HANDLE_TYPE; }
    static void release(handle_type h) { if (is_valid(h)) ::CloseHandle(h); }
    static handle_type default_value() { return INVALID_HANDLE_TYPE; }
    static bool equal(handle_type lhs, handle_type rhs) { return lhs==rhs; }
};
typedef scoped_handle<win_file_handle> scoped_win_file_handle;

This type would be unrelated to, for example, a Windows HBITMAP, although both
HANDLE and HBITMAP are void*s.

To some degree, of course, the existing smart_ptr classes already provide some
of this functionality through their deleter object. However, I believe there
are significant advantages to having separate smart_handle classes:

- Not all handles are pointers (e.g., file descriptors) and thus cannot be used
with smart_ptrs

- Semantically, handles simply aren't pointers. E.g, the pointer deference
operators make no sense for handles.

- Otherwise incompatible handles may in fact be typedef'd to the same thing -
smart_handle makes these different types, smart_ptr does not.

- smart_ptr provides pointer conversion semantics that are inappropriate for
handles

- smart_ptr assumes that an invalid value is designated by 0 - this is not
necessarily true for handles

I've uploaded the implementation to the Yahoo group's file area as
smart_handle_jm1.zip. I've included a rudimentary test case for smart_handles
whose main goal is just to exercise all of the code.

I'd certainly love to hear ideas, criticism, etc. and ultimately see this
become part of boost.

Thanks,

John Madsen

john at illura dot com.


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk