Boost logo

Boost :

From: Howard Hinnant (hinnant_at_[hidden])
Date: 2004-01-20 22:05:33


On Jan 20, 2004, at 8:20 PM, Jonathan Turkanis wrote:

> This is definitely an improvement over your earlier version! I like
> the idea of zero overhead for non-customized deletion.
>
> I had an idea today to add a policy parameter to the move_ptr which
> would determine the 'deleter storage policy'. It would be NEITHER a
> deletion policy, NOR a storage policy for the pointer; it would just
> determine how (and whether) a deleter is stored:

<snip good comments>

At the risk of over complicating this very interesting discussion, and
going off on a tangent not yet discussed, I would like to add:

Smart pointers to objects are fundamentally different than smart
pointers to arrays of objects, even if the deleters are compatible.
For example:

#include <iostream>

struct B
{
     virtual ~B()
     {
         std::cout << "~B()\n";
     }
};

struct D : B
{
     virtual ~D()
     {
         std::cout << "~D()\n";
     }
};

int main(void)
{
     B* bp = new D; // ok
     delete bp; // ok
     std::cout << "---\n";
     B* bpa = new D[3]; // ERROR!
     delete [] bpa; // ERROR!
}

Output:

~D()
~B()

---
~B()
~B()
~B()
That is, smart pointers to arrays of objects should not respect 
dervied-to-base conversions because the language does not do so for raw 
pointers.
Therefore an interface should not imply that you can handle arrays of 
objects by simply customizing the deletion policy.  Smart pointers to 
arrays of objects require a different interface, including:
*  no dervied-to-base conversions
*  no operator*()
*  no operator->()
*  operator[](size_t)
One way to accommodate this need is to create different types like:
scoped_ptr<T>
scoped_array<T>
But I suggest an alternative interface (with similar functionality):
move_ptr<T>
move_ptr<T[]>
The advantage of my suggestion boils down to nothing more than syntax.  
There are no generic coding advantages that I am aware of.  I simply 
submit that S<T[]> is slightly more intuitive than S_array<T>.
Each of:
move_ptr<T>
move_ptr<T[]>
could have a defaulted deleter policy corresponding to delete and 
delete[].  And the interfaces of the two classes can be customized as 
described above to be appropriate for objects and arrays.
I guess the basic point I'm trying to make (and none to elegantly) is 
that deletion policy is an independent issue with respect to single 
object vs array interface.  And so we need an elegant way to 
independently specify:
1.  Deletion policy
2.  Pointer to single object or Pointer to array interface
And I submit that:
S<T[], my_deleter>
is more elegant syntax than:
S_array<T, my_deleter>
Here is an obsolete example implementation of this idea (lacks deletion 
policy, and has at least one other error not pertinent to the point I'm 
trying to make):
http://home.twcny.rr.com/hinnant/Utilities/move_ptr
-Howard

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