【问题标题】:removing shared pointers from vector or map从向量或映射中删除共享指针
【发布时间】:2018-10-21 14:41:37
【问题描述】:

我目前正在学习智能指针,并尽量避免使用原始指针。

我有一个带有共享 ptrs 的向量

std::vector<std::shared_ptr<View>> mChildren;

还有一个添加和删除方法

void View::AddChild(std::shared_ptr<View> view) {
    mChildren.push_back(view);
}

void View::RemoveChild(std::shared_ptr<View> view) {
    auto removal = std::remove(mChildren.begin(), mChildren.end(), view);
    mChildren.erase(removal, mChildren.end());
}

现在在我的代码的另一部分我有一张地图

std::map<std::weak_ptr<ModelGem>,std::unique_ptr<ViewGem>,std::owner_less<std::weak_ptr<ModelGem>>> mViews;

现在,当我尝试像这样从地图中删除元素时:

for (auto iterator = mViews.begin(); iterator != mViews.end();) 
{
    if (iterator->first.expired()) 
    {
        RemoveChild(iterator->second.get());
        iterator = mViews.erase(iterator);
    }
    else 
    {
        iterator++;
    }
}

现在问题出在这里:iterator-&gt;second.get() 它告诉我它不能将类型指针的右值转换为共享 ptr。 但是,如果我使用原始指针而不是共享指针,这根本不是问题。

所以,我想知道在这种情况下,最好只使用原始指针还是使用共享指针来解决这个问题?

【问题讨论】:

  • View::RemoveChild 是否声称拥有 view 的所有权?
  • 我不知道
  • 所以,它不应该采用智能指针。有趣的阅​​读:smart-pointer-parameters/.
  • 好的,谢谢 我会读这个
  • ViewGemView是什么关系?

标签: c++ vector shared-ptr stdmap raw-pointer


【解决方案1】:

所以,我想知道在这种情况下,最好只使用原始指针还是使用共享指针来解决这个问题?

在大多数情况下,只有一种右指针类型可供使用。这并不像一个比另一个更好。正确的方法只有一种。

地图包含unique_ptr&lt;ViewGem&gt;。这意味着它拥有完全的所有权,并且不与任何其他数据结构共享。所以不可能在vector&lt;shared_ptr...&gt; 中拥有相同的对象而不会导致未定义的行为。你必须决定哪个 ds 拥有自己的船,

  1. 如果地图拥有完整所有权,请在地图中使用 unique_ptr,在矢量中使用原始 ptr
  2. 如果向量拥有所有权,请在向量中使用unique_ptr,在地图中使用原始ptr。
  3. 如果所有权与 ds 都拥有,并且该对象仅在从地图和矢量中删除时才应销毁,则在两者中都使用 shared_ptr

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-01-03
    • 1970-01-01
    • 2022-01-07
    • 1970-01-01
    • 1970-01-01
    • 2019-05-05
    • 1970-01-01
    相关资源
    最近更新 更多