It’s a question of ownership really. Who does own the underlying object? In Boost we have
- scoped_ptr and scoped_array – private ownership. I got my hands on the object and only I control it
- shared_ptr and shared_array – shared ownership with internal reference counting. Collective thinking, we own the object and anyone if free to join
- intrusive_ptr – shared ownership with custom reference counting
- weak_ptr – no ownership. I don’t own anything but I can tell you who might
And then there are std:auto_ptr and std::unique_ptr. They do ownership transfer. That is only one owner is allowed at a time.
x(new int); auto_ptr y; y = x; cout << x.get() << endl; // NULL !!! cout << y.get() << endl; // not NULL
x(new int); unique_ptr y; y = move(x); cout << x.get() << endl; // NULL !!! cout << y.get() << endl; // not NULL
A while back I read Jeff Alger book "C++ for Real Programmers". That was before Boost. I think it was written even before auto_ptr. For anyone interested in C++ history I highly recommend it. At least it will be obvious why we have such a diversity of smart pointers.