Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

weak_ptr of a base class, while the shared_ptr is of a derived class?

I have a structure that manages objects that derive from a base class Entity, but does not control their lifetimes. I want this structure to be given weak pointers like weak_ptr<Entity> so that it can know if the object has been destroyed elsewhere.

However, outside of the managing structure where the shared pointer lives, I want the shared pointer to be the more specific shared_ptr<SpecificEntity> (SpecificEntity uses Entity as a base class).

Is there a way to accomplish this, or something like it?

like image 475
Anne Quinn Avatar asked Feb 20 '13 23:02

Anne Quinn


People also ask

What is the difference between shared_ptr and weak_ptr?

The only difference between weak_ptr and shared_ptr is that the weak_ptr allows the reference counter object to be kept after the actual object was freed. As a result, if you keep a lot of shared_ptr in a std::set the actual objects will occupy a lot of memory if they are big enough.

How can a weak_ptr be turned into a shared_ptr?

The weak_ptr class template stores a "weak reference" to an object that's already managed by a shared_ptr. To access the object, a weak_ptr can be converted to a shared_ptr using the shared_ptr constructor or the member function lock.

What happens when shared_ptr goes out of scope?

All the instances point to the same object, and share access to one "control block" that increments and decrements the reference count whenever a new shared_ptr is added, goes out of scope, or is reset. When the reference count reaches zero, the control block deletes the memory resource and itself.

When should I use weak_ptr?

By using a weak_ptr , you can create a shared_ptr that joins to an existing set of related instances, but only if the underlying memory resource is still valid. A weak_ptr itself does not participate in the reference counting, and therefore, it cannot prevent the reference count from going to zero.


1 Answers

That's very possible. You can always convert a shared_ptr<Derived> to a shared_ptr<Base> implicitly, and for the other direction you have std::static_pointer_cast and std::dynamic_pointer_cast, which do what you'd expect – i.e. you end up with a new pointer of different type that shares ownership with the original pointer. Example:

std::shared_ptr<Base> p(new Derived);

std::shared_ptr<Derived> q = std::static_pointer_cast<Derived>(p);

std::shared_ptr<Base> r = q;

Or, more C++11-style:

auto p0 = std::make_shared<Derived>();

std::shared_ptr<Base> p = p0;

auto q = std::static_pointer_cast<Derived>(p);
like image 76
Kerrek SB Avatar answered Sep 19 '22 07:09

Kerrek SB