Boost logo

Boost :

From: Tom Becker (voidampersand_at_[hidden])
Date: 2002-01-17 22:51:51


On Thu, 17 Jan 2002 14:56:59 -0500, "David Abrahams"
<david.abrahams_at_[hidden]> wrote:
>----- Original Message -----
>From: "Tom Becker" <voidampersand_at_[hidden]>
> > Deleting through a pointer that doesn't have adequate type
> > information is bad. The code should either give Base a virtual
> > destructor, or it should avoid slicing the Derived* to a Base*.
> > Converting the code to use shared_ptr doesn't change its safety, or
> > lack thereof, in any way.
>
>I think many people regard smart pointers as a way of removing the unsafe
>characteristics of raw pointers, by hiding them behind a well-behaved
>interface. From that POV, eliminating release (and, for that matter,
>construction from raw pointers) is a good idea.

Definitely, many people think that way.

I'm concerned that the more we try to make a smart pointer a
replacement for, rather than a manager of, a raw pointer, the smart
pointer has to support more raw-pointer-like features, until it
faithfully replicates all the behavior it's supposed to protect us
from. Also, I can live with a simple class that doesn't fully protect
me from myself, but there's no way I can use a class that won't allow
connections to and from legacy APIs. I'm not a total expert, and I'd
love to be proven wrong, so please keep trying.

Going back to your example of the unsafe code, correct me if I'm
wrong, but I think this boils it down to the minimum:

struct Base { Base(); ~Base(); };
struct Derived : Base { Derived(); ~Derived(); };

void unsafe()
{
     shared_ptr<Base> b(new Derived);
     b.reset(); // equivalent to delete (Base*)(new Derived)!!
};

That's because, as long as shared_ptr<Base> allows construction from
a Derived*, it doesn't matter where the Derived* is obtained from.
Unfortunately, that means that tricks such as auto_ptr_ref can't save
us here.

How about adding an additional constructor:

     template<typename Y>
     explicit shared_ptr(Y* p);

that can do a static assert if Y is not delete compatible with T?
(The delete compatibility type trait test is left as an exercise to
the reader.)

Regards,

   Tom

-- 
--
Tom Becker                "Lesson zero: pointers are not your friends.
Consulting Propeller Head  Lesson one: side effects are not your friends.
<voidampersand_at_[hidden]>  Lesson two: pointers are your friends."
                                                            -- Scott Myers

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