【问题标题】:Casting weak_ptr<IBase> to weak_ptr<Derived>将weak_ptr<IBase> 转换为weak_ptr<Derived>
【发布时间】:2022-01-16 09:56:12
【问题描述】:

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

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

std::weak_ptr<IPooledObject> weakPtr = poolManager.SpawnFromPool();
if (EnemyEntity* enemy0 = reinterpret_cast<EnemyEntity*>(weakPtr.lock().get()))

C26815:指针悬空,因为它指向已销毁的临时实例。

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

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

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

【问题讨论】:

    标签: c++ smart-pointers


    【解决方案1】:

    为避免悬空指针问题,您需要确保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
    }
    

    【讨论】:

    • 可爱!非常感谢!!
    【解决方案2】:

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

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

    【讨论】:

    • 太棒了,这也有效。谢谢!
    猜你喜欢
    • 2011-04-22
    • 1970-01-01
    • 2012-07-02
    • 1970-01-01
    • 1970-01-01
    • 2012-05-04
    • 1970-01-01
    • 2011-08-29
    • 2015-12-16
    相关资源
    最近更新 更多