|
Boost : |
From: Greg Colvin (greg_at_[hidden])
Date: 2001-07-27 15:07:51
From: Philip Nash <philip.nash_at_[hidden]>
> > From: Peter Dimov [mailto:pdimov_at_[hidden]]
>
> > > just that getting into the IiRA idiom's is probably
> > > beyond the scope of shared_ptr without bloating it (which you seem to
> > agree
> > > with from the above).
> >
> > Actually neither shared_resource nor shared_ptr implements the RAII idiom.
> > (auto_ptr doesn't either.)
>
> You are right, of course.
>
> > The RAII idiom, when followed, _enforces_ the basic exception safety
> > guarantee; anything that acquires resources outside a constructor
> > does not:
The way I see it is that the use of auto_ptr and shared_ptr constructors from
raw pointers should almost always be hidden inside of factory functions or
handle object constructors. So it is unfortunate, but acceptable, that they
are prone to misuse. That said, your suggestions below are very interesting.
> One possible way of making it true IIRA/RAII (choose your prefered ordering)
> then, would be to move the initialiser function by passing that in as a
> functor too. The downside to this is that the initialiser will almost always
> have one or more parameters that you will need to supply as "constructor"
> arguments. These could be captured using binders but it would make the
> syntax unwieldy and detract from the usability.
> Having said that I can concieve of a wrapper for boost::function that would
> accept the bound arguments in their contructors, create functors that take
> no arguments and use binders to delegate to the original function (objects).
> In the case of the initializer the internal functor would return the
> "handle" object. A finalizer would return void, although it would probably
> not usually be necessary.. The parameters passed as bound arguments would be
> matched at compile time so the type safety would not be compromised (I've
> not tried this yet, so I could be missing something... just ruminating at
> present):
>
> This would allow a syntax like this (using the FILE* example again):
>
> boost::scoped_resource<FILE*>f( boost::initializer( &fopen,
> "my_file.txt", "rt" ), &fclose );
>
> What about defered initialisation, though? This would entail being able to
> set up the initializer and finalizer functions in the constructor, but then
> provide an init member that takes the initializer arguments (this is a good
> case for disallowing finalizer arguments, as this would complicate an init
> member syntax). Again the init member could be written very generally using
> parameter number overloading and templated types, but the types and number
> would still have to match internally.
> This would allow the following syntax:
>
> boost::scoped_resource<FILE*>f( &fopen, &fclose );
>
> f.init( "my_file.txt", "rt" );
>
> ... which seems quite natural.
>
> The way I see it this still constitutes RAII, because the resource
> "aquisition" is deferred to the init member (initialisation).
> If the init member is implemented by constructing a temporary object and
> using the swap idiom to exchange state then the exception guarantees of RAII
> are retained. The destructor would not call the finalizer if the object had
> not been initialised.
>
> Hmmm, this is starting to sound feasable, but I would obviously be
> interested in any comments, positive or negative (if justified).
> In the meantime I will start writing a prototype.
>
> Although I have used scoped_resource in the interface examples here,
> shared_resource would probably be the more powerful implementation for
> sharing resources. However it would also open up a whole new can of worms in
> a multithreaded environment.
> One possibility here might be to provide a typedef for locked_resource,
> which would provide a proxy for the shared resource, but would lock the
> resource internally. E.g.
>
> typedef boost::shared_resource<FILE*> SHARED_FILE;
> SHARED_FILE f( initialiser( &fopen, "my_file.txt", "rt" ), &fclose );
>
> // ..
>
> {
> SHARED_FILE::locked_resource lf( f );
>
> // use lf
> }
>
> I hear that boost::threads is nearly ready, so I would almost certainly use
> that.
>
> > I'm not saying that shared_resource is not useful; it would probably work
> > well as a building block. The danger is that when it's there
> > people will use it in unsafe ways.
>
> Well, I would like to try and minimise "unsafe ways" of using it. Perhaps
> this type of class is more open to misuse (abuse?) than most, because it
> relies on you to pass in functions with specific semantics, but as Herb
> Sutter says, we need to be careful to distinguish between protecting against
> Murphy as opposed to Machiavelli (although perhaps the distinction is not
> quite so clear cut for generic library code).
>
> > > How are you implementing the finalizer, btw? Does it allow for member
> > > functions (useful for obj->Release() style deletions)?
> >
> > std::mem_fun or
> >
> > http://www.mmltd.net/pdimov/mem_fun.html
> >
> > will take care of this.
>
> But wouldn't it have to be used internally?
>
> [)o
> IhIL..
>
>
>
>
> Info: http://www.boost.org Unsubscribe: <mailto:boost-unsubscribe_at_[hidden]>
>
> Your use of Yahoo! Groups is subject to http://docs.yahoo.com/info/terms/
>
>
>
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk