如果我有一个指向矢量元素的指针,而不是迭代器,如何删除它?
How can I delete a vector element if I have a pointer to it, not an iterator?
我遇到了一个子对象需要其父对象来销毁它的问题。我想要如下所示的内容,这只是一个例子:
#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;
}
如果我跟踪孩子在矢量中的位置,我就知道如何去做,但我基本上想知道如果我有一个指向矢量的指针,我如何擦除矢量的元素。
编辑:AndyG一直都是对的,我不能做我想做的事,因为当我"新"它时,我的对象在内存中到处都是。我确实设法使用放置 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;
}
不幸的是,唯一的方法是像往常一样搜索向量。
auto it = std::find(std::begin(children), std::end(children), child);
if (it != std::end(children)){
children.erase(it);
delete child;
}
演示
假设向量不需要排序,那么我们可以将child
元素交换到末尾,然后调整向量的大小。 此方法不需要在child
和最后一个元素之间移动向量的所有元素。
auto it = std::find(std::begin(children), std::end(children), child);
if (it != std::end(children)){
std::iter_swap(children.rbegin(), it);
children.resize(children.size() - 1);
delete child;
}
相关文章:
- 在C++中释放内存期间,迭代器与指针有何不同
- 使用迭代器 C++ 删除矢量中的重叠字符串
- C++:在进行切片时对迭代器的约定,特别是对于访问最后一个元素并最终将其删除
- 如何使用擦除和迭代器来删除二维向量中的项目
- 如果我有一个指向矢量元素的指针,而不是迭代器,如何删除它?
- c++ 在循环中删除迭代器(映射的映射)
- 从矢量C++中删除时,矢量迭代器不可取消引用
- 为什么擦除-删除成语不适用于反向迭代器
- 通过反向迭代器从矢量快速删除
- debug断言矢量迭代器不可用find_if删除
- 如何在不使用循环或迭代器的情况下检查所有列表元素并在满足条件时删除一个
- 如何在给定迭代器列表的情况下从向量中删除元素
- 射击时从列表中删除外星人 - 找出循环;"表达式:无法递增结束列表迭代器"
- 使用迭代器指针 (C++) 从对象指针列表中删除元素
- 为什么删除字符串迭代器会产生const char参考
- 迭代器:如果 '*' 返回元素的引用,为什么删除 *(myList.end()) 会给出 SegFault
- 在迭代器时从 std::list 中删除条目
- C++:从映射中删除迭代器,然后递增到下一个迭代器
- erase删除迭代器所指向的元素失败时的处理方法
- c++不需要删除迭代器