如何通过指针删除向量元素?

8
我有这个:
vector<Object*> myVec;

并像这样将我的对象添加到其中:
Object *obj1 = new Object;
myVec.push_back(obj1);

假设我有100个对象,指针分别为*obj1、*obj2......*obj100。
现在我想从向量中删除obj37。我希望我可以像推送一样做到这一点:
myVec.remove_back(obj37);

如果有一个类似于“remove_back”的函数就好了,但我想没有这样的函数。

希望你明白我的意思并帮我解决问题。

顺便提一下,看看这个问题,在被接受的答案中,有一个按值工作的删除算法:

vec.erase(std::remove(vec.begin(), vec.end(), 8), vec.end());

我试着使用指针,即使我自己也不相信它会起作用,但令人惊讶的是,它并没有起作用:

myVec.erase(std::remove(myVec.begin(), myVec.end(), *obj37), vec.end());

是的,我知道我刚才说了一些废话,但那是为了让你明白。某个地方应该有一个像这样简单的解决方案,我只是想要那个。


1
简单的解决方案是不要手动管理内存。如果你真的需要指针,请使用智能指针。然而,由于你有一组指针,如果你想比较解引用后的指针而不是指针本身,你需要为 std::remove_if 提供自己的比较器。 - chris
如果你确定你的程序需要vector提供给你的功能,那我建议你将数据结构从std::vector<Object*>改为std::map<int, Object*>。 - antonpp
@chris 是的,我曾经使用过boost shared_ptrs,但在阅读了一篇好文章后,我已经将它们移除了。此外,我只想自己做所有事情,因为我是C++和OOP的新手,并相信这会让我更好。我会寻找std::remove_if。谢谢。 - allyozturk
3个回答

14

你已经快完成了:通过值 搜索元素

myVec.erase(std::remove(myVec.begin(), myVec.end(), obj37), myvec.end());
//                                                  ^^^^^

或者,如果您知道该元素在位置36(从0开始计数),则可以直接删除它:

myvec.erase(myvec.begin() + 36);

或者,在现代C ++中:

myvec.erase(next(begin(myvec), + 36));

还要注意,std::remove 会搜索整个向量,因此如果你知道只有一个元素,可以使用 find 来停止查找:

{
    auto it = std::find(myVec.begin(), myVec.end(), obj37);
    if (it != myVec.end()) { myVec.erase(it); }
}

哦,来吧 :) 我现在感觉好蠢啊 :) 怎么没想到不用 * 呢?而且我不能通过位置删除它,因为 obj37 只是我的假设,我不知道它在我的东西中的位置。myVec.erase(std::remove(myVec.begin(), myVec.end(), obj37), myvec.end()); 真是太棒了。非常感谢。 - allyozturk
4
如果您无法编译这段代码,请不要忘记添加#include <algorithm> - B Faley

2

std::remove()函数会删除与其最后一个参数匹配的值。也就是说,您可以像这样删除指针:

myVec.erase(std::remove(myVec.begin(), myVec.end(), ptr), myVec.end());

如果只有一个元素匹配,使用std::find()可能比使用std::remove()更容易。如果你实际上想匹配指向的值,你可以使用带有适当谓词的算法的_if版本。当然,删除指针不会释放任何内存。


-1
如果您使用C++11,可以将智能指针放入向量中。然后,您可以使用erase方法来删除对象,智能指针会自动处理删除指针的内容。
vector<std::shared_ptr<Object>> myVec;

shared_ptr内部有一个引用计数器。如果对象没有被任何变量引用,它将自动删除。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接