简体   繁体   中英

Casting weak_ptr<IBase> to weak_ptr<Derived>

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?

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
}

You may do it in a single line with help of static pointer cast

std::weak_ptr<Derived> enemy0 = std::static_pointer_cast<Derived>(poolManager.SpawnFromPool().lock());

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM