【问题标题】:C++: Deleting an Object in a static vector of pointers with the destructor?C ++:使用析构函数删除静态指针向量中的对象?
【发布时间】:2015-01-10 03:22:00
【问题描述】:

我的班级是这样设置的:

class Foo{
    public:
    Foo();
    ~Foo();

    static vector<Foo*> foos;
}

Foo::Foo(){
    foos.push_back(this);
}
Foo::~Foo(){}

假设我像这样创建了一个对象Foo

int main(){
    Foo *obj = new Foo();
}

我将如何删除这个对象以及静态向量中的指针?

【问题讨论】:

  • 两者都使用std::unique_ptr,那么您就不必担心了。
  • 您的代码中有几个拼写错误。

标签: c++ pointers vector static destructor


【解决方案1】:

Foo::~Foo的实现改为

Foo::~Foo()
{
    foos.erase(std::find(foos.begin(), foos.end(), this));
}

...使用std::unique_ptr...

int main(int argc, char **argv)
{
    std::unique_ptr<Foo> ptr{new Foo{}};

    return 0;
}

...它会自行清理。

问题包括:

  • 不是线程安全的。
  • 对于 n 个实例,每次删除的最坏情况时间为 O(n)
  • 邪恶的全球状态!

如果您对以上内容没问题,请继续扣动扳机!

【讨论】:

  • 如何将迭代器存储为成员以防止 O(n) 时间?
  • std::vector 的后备存储是连续的。此外,指向元素的迭代器在容器突变后失效。如果一个较旧的元素需要在一个较新的元素之前被销毁,则向量中其指针之后的所有指针都需要向下移动。这是 O(n) 最坏的情况。
  • @defube 也许 std::list 可以做到? “在列表中或跨多个列表添加、删除和移动元素不会使迭代器或引用无效。仅当删除相应的元素时,迭代器才会失效。”,来自cppreference
  • 是的。不过,它仍然是全球状态。请记住,std::list 与任何其他基于节点的数据结构一样,需要在每次突变时戳它的分配器——但你已经知道了。
猜你喜欢
  • 2020-12-27
  • 2013-05-21
  • 1970-01-01
  • 2013-12-21
  • 2012-07-02
  • 2021-07-25
  • 2011-06-10
  • 1970-01-01
  • 2011-05-02
相关资源
最近更新 更多