I am trying to create object pooling with an interface base using smart pointers. However I cannot access the derived object without casting it from a weak_ptr to a raw pointer, which kind of kills the purpose of smart pointers. Also it warns me it is vulnerable to the dangling pointer state.
Yes the code compiles, but I don't like warnings and at the moment it shouldn't be 100% safe regardless.
std::weak_ptr<IPooledObject> weakPtr = poolManager.SpawnFromPool();
if (EnemyEntity* enemy0 = reinterpret_cast<EnemyEntity*>(weakPtr.lock().get()))
C26815: The pointer is dangling because it points at a temporary instance which was destroyed.
Now what I actually want instead is to cast the weak_ptr with IPooledObject returned from poolManager.SpawnFromPool() into another weak_ptr with the derived class EnemyEntity instead.
std::weak_ptr<EnemyEntity> enemy0 = poolManager.SpawnFromPool();
The last code snippet is how I ideally want to use it, but it doesn't compile. I can't figure out the correct syntax myself how to cast between the two weak pointer types (from IBase to Derived). Could anyone help?
CodePudding user response:
To avoid the dangling pointer issue you need to ensure that a shared_ptr
will be alive for the entire time you need access to the object. Then, use dynamic_pointer_cast
to execute a dynamic_cast
on the pointee:
if (auto sharedPtr = weakPtr.lock()) {
std::weak_ptr enemy0 = std::dynamic_pointer_cast<EnemyEntity>(sharedPtr);
} else {
// weakPtr has expired
}
CodePudding user response:
You may do it in one line with help of static pointer cast
std::weak_ptr<Derived> weakPtr2 = std::static_pointer_cast<Derived>(weakPtr.lock());