【问题标题】:Is it possible to convert a const unique_ptr reference (derived class) to a shared_ptr (base class)是否可以将 const unique_ptr 引用(派生类)转换为 shared_ptr(基类)
【发布时间】:2019-01-04 20:51:20
【问题描述】:
std::vector<std::unique_ptr<Projectile>> const& projectiles = m_projectileManager->GetProjectiles();
std::vector<std::vector<std::unique_ptr<Enemy>>> const& enemies = m_enemyManager->GetEnemies();

std::vector<std::unique_ptr<EntityBoundingBox>> boundingBoxes;
for (std::unique_ptr<Projectile>const& projectile : projectiles) {
    std::shared_ptr<Entity> entity = std::move(projectile); //error

    std::unique_ptr<EntityBoundingBox> boundingBox = std::make_unique<EntityBoundingBox>(projectile->GetBoundingBox(), entity);
    boundingBoxes.push_back(std::move(boundingBox));
}

我正在尝试创建一个新对象 EntityBoundingBox,但我需要保留对原始 Entity 的引用以确定与什么发生冲突,但由于我对实体使用 unique_ptr,所以我可以'似乎没有把它们传给新班级。另外我正在尝试存储Entity 类型,它是Projectile 的基类

有没有办法做到这一点,而无需从 unique_ptr 更改为 shared_ptr 来存储 ProjectileEnemy 对象并删除 const 限定符?

EntityBoundingBox 的构造函数

EntityBoundingBox(std::shared_ptr<BoundingBox> boundingBox, std::shared_ptr<Entity> entity)

【问题讨论】:

  • 否,因为对 const 限定 std::unique_ptr 的引用无法释放指针的所有权。
  • 好吧,如果其他东西也存储了一个指向射弹的拥有指针,那么unique_ptr 不再是唯一的所有者......
  • 换个角度看,你不能共享一个唯一对象的所有权。有问题的不是派生/基础指针部分
  • 可以unique_ptr创建一个shared_ptr 如果你的std::moveunique_ptr变成shared_ptr。但是正如@VTT 所提到的,如果您的unique_ptrconst 并且在保留原始unique_ptr 的同时无法做到这一点(它不再是唯一的所有者),这是不允许的。

标签: c++ smart-pointers


【解决方案1】:

不,原因如下:如果您只有unique_ptr&lt;&gt;const&amp;,您无权延长被引用对象的生命周期。当底层的unique_ptr 引用消失时,对象也会消失。但是如果你有shared_ptr&lt;&gt;,你确实有权延长被引用对象的生命周期。因此,仅凭您所拥有的,您无法提供所需的。

想一想为什么您会将shared_ptr 传递给某些代码可能会有所帮助。除非该代码可能需要延长被引用对象的生命周期,否则传递引用更有意义。如果您传递的是shared_ptr,那是因为该代码可能会复制该shared_ptr 并期望它延长对象的寿命。如果有其他东西会破坏该对象,那无论如何都是行不通的。

【讨论】:

  • 感谢您的回答。在这种情况下,我不确定到底该怎么做。我希望将Entity 传递给EntityBoundingBox 构造函数并临时存储它,但我读过将引用存储为类成员是不好的。所以我认为使用shared_ptr 可能是唯一的方法。
  • 这真的归结为如何管理Entity 的生命周期。如果您希望它一直持续到两个代码路径都不需要它,那么从一开始就使用make_shared 构造它,并将shared_ptrs 存储到它。代码不应采用shared_ptr,除非它想要/需要延长对象的寿命。
  • 我想我应该说你实际上可以做到这一点。你构造了一个带有空删除器的shared_ptr。如果任何代码试图通过shared_ptr 延长对象的生命周期,它将失败,但只要您 100% 确定不需要这样做,它就会正常工作。这将很难理解和维护,绝对是您应该避免的事情。不过,这比在类中存储引用要糟糕得多。
  • 是的,我不认为我会走这条路。我想我已经使用weak_ptr 实现了我想要的。我不确定它是否是一个正确的用例,但它似乎是我正在寻找的。​​span>
猜你喜欢
  • 2021-02-18
  • 1970-01-01
  • 2018-02-25
  • 2021-04-12
  • 2014-03-09
  • 1970-01-01
  • 2017-01-08
  • 2013-11-17
相关资源
最近更新 更多