|
Boost : |
From: Phil Bouchard (philippe_at_[hidden])
Date: 2008-08-29 23:21:28
"Scott McMurray" <me22.ca+boost_at_[hidden]> wrote in message
news:fa28b9250808290914l19a6cf1fue658229148ec0f09_at_mail.gmail.com...
[...]
> It's not an allocator, and it's often useful in strange ways:
>
> shared_ptr<FILE> f( fopen("file.txt"), fclose );
>
> The fact that the deleter is specified on initialization is also
> essential in that it allows you to create shared_ptrs to incomplete
> types:
>
> struct S { auto_ptr<S> p; }; // illegal
> struct S { shared_ptr<S> p; }; // fine
>
> So I don't really see your point, here.
I think you're confusing the allocator and the deleter but I am exclusively
referring to the allocator. I just looked at the code of shared_ptr today
and it is very similar to what I wrote yesterday:
template<class P, class D, class A>
class sp_counted_impl_pda: public sp_counted_base
{
...
virtual void destroy() // nothrow
{
typedef typename A::template rebind< this_type >::other A2;
A2 a2( a_ );
this->~this_type();
a2.deallocate( this, 1 );
// ugh!
}
};
This is ill-formed code. It's obvious shared_ptr is still in its
theoretical stage as far as the allocator is concerned; because
std::allocator is a bad example to start with. Let's take a real one like
the following:
// allocator
template <typename T>
class my_allocator
{
boost::fast_pool_allocator pool_;
...
void deallocate(pointer & p)
{
pool_.deallocate(p.release());
// do not touch "this" anymore starting here!!
}
};
The way shared_ptr works right now, the pool is going to be copied entirely
on to the sp_counted_impl_pda object. The problem here is that the pool is
going to delete its own instance when deallocate() is called. The allocator
variable sp_counted_impl_pda::a_ will need to be changed for a functor or a
global function pointer before anything else.
Moreover using and allocator explicitly using release() saves some
unnecessary overhead for tested classes and library programmers. One might
wonder why using a smart pointer for well tested classes? Well it turns out
shifted_ptr is much more efficient this way because all node allocations
will be part of the same set.
-Phil
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk