c++ - 如果我有一个指向 vector 元素的指针,而不是迭代器,我该如何删除它?

标签 c++ vector iterator erase

我遇到一个子对象需要其父对象销毁它的问题。我想要类似下面的东西,这只是一个例子:

#include <iostream>
#include <vector>

struct Object
{
    Object(Object* parent) : parent(parent) {}
    Object* parent;
    std::vector<Object*> children;
    bool flag = false;
    void update() { if (flag) parent->deleteChild(this); } // Or mark it for deletion afterwards
    void deleteChild(Object* child) { delete child; /*children.erase(/* I need the iterator here);*/ }
};

int main()
{
    Object* parent = new Object(nullptr);
    for (int i = 0; i < 100; ++i) parent->children.push_back(new Object(parent));

    parent->children[42]->flag = true;

    for (auto i : parent->children) i->update();

    return 0;
}

如果我跟踪 child 在 vector 中的位置,我知道该怎么做,但我基本上想知道如果我有指向它的指针,我如何删除 vector 的元素。

编辑:AndyG 一直都是对的,我不能做我想做的事,因为当我“新建”它时,我的对象在内存中到处都是。我确实设法使用 placement new 以另一种方式做到这一点,在一个连续的缓冲区中创建所有对象,但这绝对不值得麻烦。不过,我确实学到了很多东西。

#include <iostream>
#include <vector>

struct Object
{
    Object(Object* parent, int position) : parent(parent), numberPosition(position)
    {
        std::cout << "Constructing object number: " << numberPosition << " at at heap memory location: " << this << '\n';
    }

    Object* parent;
    int numberPosition = 0;
    std::vector<Object*> children;
    bool flag = false;
    void update() 
    { 
        if (flag) parent->deleteChild(this); 
    } 
    void deleteChild(Object* child) 
    { 
        Object* pChild = &(*child);
        ptrdiff_t position = child - *children.data();
        std::vector<Object*>::iterator it = children.begin() + position;
        std::cout << "About to delete vector element at position: " << (*it)->numberPosition << '\n';

        // delete pChild;   Not supposed to deallocate each placement new. See http://www.stroustrup.com/bs_faq2.html#placement-delete and https://stackoverflow.com/questions/222557/what-uses-are-there-for-placement-new
        std::cout << "Size of children vector = " << children.size() << '\n';
        children.erase(it);
        std::cout << "Size of children vector = " << children.size() << '\n';
    }
    ~Object() { std::cout << "Destroying object number " << numberPosition << '\n'; }
};

int main()
{
    Object* parent = new Object(nullptr, 0);
    char* contiguousBuffer = static_cast<char*>(malloc(100 * sizeof(Object)));
    for (int i = 0; i < 100; ++i)
    {
        Object* newAddress = new (contiguousBuffer + i * sizeof(Object)) Object(parent, i); // Placement new
        parent->children.push_back(newAddress);
    }

    parent->children[42]->flag = true;

    //for (auto i : parent->children) i->update();  // Iterator gets invalidated after erasing the element at 42 doing it this way
    for (int i = 0; i < parent->children.size(); ++i) parent->children[i]->update();


    free(contiguousBuffer); 
    // Destructors also need to be called

    return 0;
}

最佳答案

不幸的是,唯一的方法是像平常一样搜索 vector 。

auto it = std::find(std::begin(children), std::end(children), child);

if (it != std::end(children)){
   children.erase(it);
   delete child;
}

Demo

关于c++ - 如果我有一个指向 vector 元素的指针,而不是迭代器,我该如何删除它?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45394018/

相关文章:

c++ - 为我的链表实现一个迭代器类。 using关键字是什么?

c++ - 文件系统::路径构造函数调用失败

c++ - 在 C++ vector 中使用取消引用运算符

c++ - boost (反)序列化派生对象的 vector ,使用删除函数(unique_ptr)

c++ - 如何使用 std::istreambuf_iterator 初始化字符串

python - 无法在 python 2.7 中迭代元组

c++ - 如何为 ON_COMMAND 处理程序声明 ID?

c++ - 使用其他文件构建 gcc 插件

c++ - 为什么在将临时变量传递给线程函数时移动构造函数会被调用两次?

c++ - vector n 维 vector 本身具有特定的数据类型