Boost logo

Boost :

From: Phil Nash (phil.nash.lists_at_[hidden])
Date: 2002-04-19 11:26:12


> From: "Phil Nash" <phil.nash.lists_at_[hidden]>
> > Certainly I am in violent agreement that smart_resource like
capabilities
> > should be made available somewhere (so SmartPtr capabilities applied to
> non
> > pointers).
>
> Take a look:
>
> #include <boost/shared_ptr.hpp>
> #include <iostream>
>
> typedef int HANDLE;
>
> HANDLE CreateHandle()
> {
> return 5;
> }
>
> void CloseHandle(HANDLE h)
> {
> std::cout << "CloseHandle(" << h << ")\n";
> }
>
> class shared_handle
> {
> public:
>
> explicit shared_handle(HANDLE h): h_(h), c_(h, CloseHandle)
> {
> }
>
> HANDLE get() const
> {
> return h_;
> }
>
> private:
>
> HANDLE h_;
> boost::detail::shared_count c_;
> };
>
> int main()
> {
> shared_handle h(CreateHandle());
> shared_handle h2(h);
> }

Sorry to quote so much here - it was an all or nothing. I chose all.
I'm not 100% sure what you are trying to point out here (all you say, in
addition to the code, is "Take a look").
I assume you are trying to illustrate that a shared resource wrapper is
easily written using what we already have (in this case,
boost::detail::shared_count).
However, you still have to write the class shared_handle. It might be very
simple in your example but, I will argue, could be more complex. In
particular, you only offer shared_handle here. What about scoped_handle,
auto_handle (for want of a better name), or other choices that you may want
to parameterise (if we go for a Loki::SmartPtr like implementation)?

Taking your example above I am aiming for something that might look like
this:

// --------- this bit the same as your original ------------
typedef int HANDLE;

HANDLE CreateHandle()
{
 return 5;
}

void CloseHandle(HANDLE h)
{
 std::cout << "CloseHandle(" << h << ")\n";
}

// --------- your class definition reduces down to: ------------

typedef boost::shared_resource<HANDLE> shared_handle;

// --------- then main becomes: --------------------
int main()
{
 shared_handle h(CreateHandle(), &CloseHandle );
 shared_handle h2(h);
}

This is one way to do it. And this already gives us a number of advantages
(in addition to saving keystrokes, that is) - such as being able to
parameterise the behaviour further for _all_ shared_resources, rather than
just shared_handle.
What I am not so keen on here is that we have to pass CreateHandle and
CloseHandle into the constructor on a case by case basis, rather than by
type. I've not found a compelling way yet of acheiving this by type (but I
have not given it enough thought yet either). I don't like the idea of an
open policy and a close policy (or an open_close policy), since, in the
simple cases, we end up with something like the hand written version but in
two classes. However this could be an option.

Regards,

[)o
IhIL..


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