将 weak_ptr<IBase> 转换为 weak_ptr<Derived>

Casting weak_ptr<IBase> to weak_ptr<Derived>

我正在尝试使用智能指针创建具有接口基的对象池。但是,如果不将派生对象从 weak_ptr 转换为原始指针,我将无法访问派生对象,这会扼杀智能指针的用途。它还警告我它容易受到悬挂指针状态的影响。

是的,代码可以编译,但我不喜欢警告,而且目前无论如何都不应该是 100% 安全的。

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.

现在我真正想要的是将 weak_ptr 和从 poolManager.SpawnFromPool() 返回的 IPooledObject 转换为另一个 weak_ptr 和派生的 class EnemyEntity。

std::weak_ptr<EnemyEntity> enemy0 = poolManager.SpawnFromPool();

最后一个代码片段是我最理想的使用方式,但它无法编译。我自己无法弄清楚如何在两种弱指针类型(从 IBase 到 Derived)之间进行转换的正确语法。有人能帮忙吗?

为避免悬挂指针问题,您需要确保 shared_ptr 在您需要访问该对象的整个过程中都处于活动状态。然后,使用 dynamic_pointer_cast 在指针对象上执行 dynamic_cast

if (auto sharedPtr = weakPtr.lock()) {
    std::weak_ptr enemy0 = std::dynamic_pointer_cast<EnemyEntity>(sharedPtr);
} else {
    // weakPtr has expired
}

您可以在静态指针转换的帮助下在一行中完成

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