如何在不同的标准::矢量中删除相同的指针?

How to delete same pointer in different std::vector's?

本文关键字:删除 指针 标准      更新时间:2023-10-16

我的游戏主循环如下:

std::vector<std::unique_ptr<State>> states;
for(size_t i = 0; i < states.size(); i++)
{
     states[i]->Update();
     states[i]->Draw();
}

不过,他们在这方面存在缺陷。在迭代过程中,我不能修改向量(删除状态),因为如果我删除了迭代正在进行的当前状态,那么它显然会中断,因为没有状态可以调用update和drawing。所以我认为,制作一个应该添加到states向量的状态向量,并制作一个应删除到states向量的状态矢量是一个好主意。然后,在循环结束后,修改states向量,并且在迭代中期不会出现问题。

std::vector<std::unique_ptr<State>> states;
std::vector<std::unique_ptr<State>> statesToBeAdded;
std::vector<std::unique_ptr<State>> statesToBeRemoved;
for(size_t i = 0; i < states.size(); i++)
{
    states[i]->Update();
    states[i]->Draw();
}
for(size_t i = 0; i < statesToBeAdded.size(); i++)
{
    states.push_back(std::move(statesToBeAdded[i]));
}
statesToBeAdded.clear();
for(size_t i = 0; i < statesToBeRemoved.size(); i++)
{
    states.erase(std::remove(states.begin(), states.end(), statesToBeRemoved[i]), states.end());
}
statesToBeRemoved.clear(); //error is thrown here

不过,我无法从states向量中删除状态,在statesToBeRemoved.clear()行上引发了一个错误,我认为这是因为当我调用states.erase(...)行时,它从states向量中删除了元素,从而使statesToBeRemoved向量中的相同元素无效,因为该元素指向一个不再存在的对象。

你不能只删除std::unique_ptr而不破坏指针指向的内容,所以我认为没有办法在不使statesToBeRemoved向量中的元素无效的情况下从states向量中删除元素。那么如何解决这个问题呢?

谢谢。

不同的指针类型满足不同的所有权语义:

  • unique_ptr用于唯一所有权,这就是当前代码不起作用的原因
  • shared_ptr用于共享所有权-当管理对象的最后一个shared_ptr超出范围时,它将被销毁
  • 原始指针(*)并没有真正说明它们正在建模的语义,但您必须手动强制执行所有约束——这就是它们的危险所在。然而,对于从不拥有所指向对象所有权的指针来说,它们是安全的(在我看来是明智的选择)

所以:你的statesToBeAdded是安全的,只要你能保证你永远不会有任何不在states中的东西。statesToBeRemoved不同:对象已经在states中,让states拥有对象的所有权是有意义的,因此原始指针对于statesToBeRemoved来说是一个公平的选择。

请注意,所有这些都是基于您显示的几行代码,根据具体情况,在您的states中存储State s而不是unique_ptr<State> s很可能是有意义的,等等。。。