Why don't smart pointers have the same semantics as plain pointers?

classic Classic list List threaded Threaded
5 messages Options
Reply | Threaded
Open this post in threaded view
|

Why don't smart pointers have the same semantics as plain pointers?

Pierre THIERRY
I use more and more BOOST smart pointers instead of plain pointers in my
C++ code, and it is incredible how it saves time and prevent bugs!

But I was wondering why one couldn't just change the type of a pointer a
keep all code as it is, instead of having to change affectation to
reset(), for example.

E.g., the following code:

Foo* ptr_foo;
ptr_foo = new Foo;

Has now to be changed to:

shared_ptr<Foo> ptr_foo;
ptr_foo.reset(new Foo);

But I'd like it to be:

shared_ptr<Foo> ptr_foo;
ptr_foo = new Foo;

Is there a problem to have shared_ptr<T>::operator=(T*)?

Curiously,
Nowhere man
--
[hidden email]
OpenPGP 0xD9D50D8A


_______________________________________________
Boost-users mailing list
[hidden email]
http://lists.boost.org/mailman/listinfo.cgi/boost-users
Reply | Threaded
Open this post in threaded view
|

Re: Why don't smart pointers have the same semantics as plain pointers?

me22
On 16/01/06, Pierre THIERRY <[hidden email]> wrote:
> Is there a problem to have shared_ptr<T>::operator=(T*)?
>

As I understand it, it's not allowed so that it's very clear when it's
done.  Once a pointer ends up in a shared_ptr, there's no way to get
it out of one, so independently creating 2 shared_ptrs that both own
the same memory location is a recipe for disaster.

There's always "shared_ptr<Foo> ptr_foo( new Foo );", which is less
typing than either anyways.

- Scott

_______________________________________________
Boost-users mailing list
[hidden email]
http://lists.boost.org/mailman/listinfo.cgi/boost-users
Reply | Threaded
Open this post in threaded view
|

Re: Why don't smart pointers have the same semantics as plain pointers?

Pierre THIERRY
Le Mon, 16 Jan 2006 20:16:14 -0500, me22 a écrit :
>> Is there a problem to have shared_ptr<T>::operator=(T*)?
> As I understand it, it's not allowed so that it's very clear when it's
> done.

OK, but that shouldn't be allowed to be clear when it's done only if
there's a risk using this assignation.

> Once a pointer ends up in a shared_ptr, there's no way to get it out
> of one, so independently creating 2 shared_ptrs that both own the same
> memory location is a recipe for disaster.

Who said it had to be independent? As I see it, the implementation could
be:

    shared_ptr & operator=(T * r)
    {
            reset(r);
            return *this;
    }

> There's always "shared_ptr<Foo> ptr_foo( new Foo );", which is less
> typing than either anyways.

But only possible at the construction. In any other place, you have to
use reset. And the problem is, I have to modify deeply my code to use
shared_ptr, and change it back if I stop using them.

With the operator=(T*), it would need no more than a modified typedef
for the entire code to switch to or from shared_ptr (or from any other
type of pointer that supports this operator).

Simply,
Nowhere man
--
[hidden email]
OpenPGP 0xD9D50D8A


_______________________________________________
Boost-users mailing list
[hidden email]
http://lists.boost.org/mailman/listinfo.cgi/boost-users
Reply | Threaded
Open this post in threaded view
|

Re: Why don't smart pointers have the same semantics as plain pointers?

Thorsten Ottosen
Pierre THIERRY wrote:
> Le Mon, 16 Jan 2006 20:16:14 -0500, me22 a écrit :

>>There's always "shared_ptr<Foo> ptr_foo( new Foo );", which is less
>>typing than either anyways.
>
>
> But only possible at the construction. In any other place, you have to
> use reset. And the problem is, I have to modify deeply my code to use
> shared_ptr, and change it back if I stop using them.
>
> With the operator=(T*), it would need no more than a modified typedef
> for the entire code to switch to or from shared_ptr (or from any other
> type of pointer that supports this operator).

Just replacing shared_ptr<T> with T* seems to require much more than
just a typedef. If the goal is to replace boost::shared_ptr<T> with
foo::shared_ptr<T>, you might look into traits.

-Thorsten

_______________________________________________
Boost-users mailing list
[hidden email]
http://lists.boost.org/mailman/listinfo.cgi/boost-users
Reply | Threaded
Open this post in threaded view
|

Re: Why don't smart pointers have the same semantics as plain pointers?

Tom Widmer
In reply to this post by Pierre THIERRY
Pierre THIERRY wrote:

>>Once a pointer ends up in a shared_ptr, there's no way to get it out
>>of one, so independently creating 2 shared_ptrs that both own the same
>>memory location is a recipe for disaster.
>
>
> Who said it had to be independent? As I see it, the implementation could
> be:
>
>     shared_ptr & operator=(T * r)
>     {
>    reset(r);
>    return *this;
    }

Yes, but:

shared_ptr<Foo> fooptr;
Foo* ptr = new Foo;
fooptr = ptr;
fooptr = ptr; //boom

There are thousands of possible bugs like the above that can be caused
by an "automatic" shift to shared_ptr - remember, a shared_ptr must be
the *unique* owner of a raw pointer.

>>There's always "shared_ptr<Foo> ptr_foo( new Foo );", which is less
>>typing than either anyways.
>
>
> But only possible at the construction. In any other place, you have to
> use reset. And the problem is, I have to modify deeply my code to use
> shared_ptr, and change it back if I stop using them.

You can avoid that:

typedef shared_ptr<Foo> fooptr;
fooptr p;
//...
f = fooptr(new Foo);

That doesn't need to change if you change back to:
typedef Foo* fooptr;
However, that change is unlikely to work (since you'll suddenly have
memory leaks at best), but you could at least quite easily change to:
typedef mysmartptr<Foo> fooptr;

> With the operator=(T*), it would need no more than a modified typedef
> for the entire code to switch to or from shared_ptr (or from any other
> type of pointer that supports this operator).

Changing the typedef like that is likely to introduce a huge number of
bugs to your code! Remember, when a shared_ptr is given a raw pointer,
it takes ownership of that pointer. If anything else still owns that
pointer (or multiple shared_ptrs are separately given ownership of the
raw pointer), your code is going to perform double deletions. Requiring
explicit transfer at least forces you to examine every ownership
transfer in the code to make sure it is valid, and to change it if not.

Tom

_______________________________________________
Boost-users mailing list
[hidden email]
http://lists.boost.org/mailman/listinfo.cgi/boost-users