Home > Net >  Casting weak_ptr<IBase> to weak_ptr<Derived>
Casting weak_ptr<IBase> to weak_ptr<Derived>

Time:12-13

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());
  • Related