删除矢量中的对象

问题描述:

我想删除对象矢量中的元素。该向量填充了Object的实例,并且在某些时候,我想要删除矢量中的某个元素,而不是索引,但是由元素本身删除。删除矢量中的对象

一个简单的例子是:

std::vector<string> strVector; 
strVector.push_back("abc"); 
strVector.push_back("def"); 
strVector.push_back("ghi"); // So strVector should contain "abc", "def", and "ghi" 

如何从载体中删除 “GHI”?请注意,我不知道该矢量中的“ghi”在哪里。

// Something like this. Assume strVector = [ "abc", "cba", "ccb", "bac", "aaa" ] 
strVector.removeElement("ccb"); 

更相关的例子,我一个工作:

class MyClass { 
    std::vector<Object> myObjVector; 
    void main(ARGS) { 
     for (int i = 0; i < 10; i++) { 
     Object myObject = Object(); 
     myObjVector.push_back(myObject); 
     } 

     int j = getANumber(); // j could be any number within the size of the vector 
     Object myOtherObject = myObjectVector.at(j); 

     // How do I erase myOtherObject (which is an object inside the vector) ? 
     removeFromVector(myOtherObject); 
    } 
} 

我希望这个问题的明确。提前致谢。

编辑:我想通了,谢谢所有回答。诀窍是给这个类赋予唯一的标识它的东西(比如名字或标签,只要它们保证是唯一的),然后使用erase-remove idiom从数组中删除对象。

+1

你有矢量内的重复吗? – 2012-08-02 08:37:11

+0

不,我不知道。在创建Object的实例后,我立即将它推入向量中,这意味着向量的所有元素都是新创建的元素。 – alxcyl 2012-08-02 08:40:54

+0

检查一些[文档](http://en.cppreference。com/w/cpp/container/vector),它应该帮助找到例如['erase'](http://en.cppreference.com/w/cpp/container/vector/erase)函数。 – 2012-08-02 08:41:45

如果你的用例没有重复,那么你最好使用std::set并使用std::set::erase这个值。

std::set<string> strSet; 
strSet.insert("abc"); 
strSet.insert("def"); 
strSet.insert("ghi"); 
strSet.insert("ccb"); 

strSet.erase("ccb"); 

如果您需要处理重复项,则必须指定所需的删除行为。它是否应该删除一个或所有匹配值的元素?你关心保留剩余元素的顺序吗?如果您需要使用矢量,则请在erase-remove idiom处输入lokk。但请注意,std::vector::erase具有线性时间复杂度,而相关变体std::set::erase具有对数时间复杂度。擦除删除将删除所有元素等于给定的值。

注意:如果你想使用std::set为用户定义类型,你必须提供一个小于bool operator<(const UserType&) const或比较函数或仿函数,实现strict weak ordering

+0

我会尽力而为,谢谢。 – alxcyl 2012-08-02 08:42:13

+0

不,从理论上讲,不应该有重复,因为我在实例化之后立即推送事物。没有必要保存命令,只需删除Object的一个/ vector/array /集合中的'Object'实例 – alxcyl 2012-08-02 08:47:07

+2

@LanceGray:你说应该没有重复,但在你的例子中,你在向量中插入10个相同的对象(好吧,我们没有'Object'的定义,所以这是一个猜测)。你知道参考语义和价值语义之间的区别吗?例如,你是否意识到,即使它们是两个不同的对象,std :: string s1(“s”)'和'std :: string s2(“s”)'是否相等? 's1 == s2'。 – 2012-08-02 10:04:46

如果你必须使用一个vector,然后使用erase(remove())

#include <algorithm> 
#include <string> 
#include <vector> 

strVector.erase(std::remove(strVector.begin(), strVector.end(), "ghi"), 
       strVector.end()); 

这将从strVector去除"ghi"所有实例。

+0

不,我不限于矢量。我也尝试过使用'erase(remove())',但它仍然不起作用。 (顺便说一下,我在Xcode和cocos2d-x中编码) – alxcyl 2012-08-02 08:45:45

+1

@LanceGray,它确实有效。参见演示http://ideone.com/vNaPj。 – hmjd 2012-08-02 08:47:41

+0

它给出了一个错误,说“无效的操作数到二进制表达式('对象'和'常量对象')”(其中'对象'是我写的类的名称)。它也指向'stl_algo.h'头上的很多'if'行。 – alxcyl 2012-08-02 09:04:07

#include <iostream> 
#include <vector> 

class Object 
{ 
public: 
    Object(int n){secret_num = n;} 
    virtual ~Object(){} 
    int getSecretNum(){return secret_num;} 

private: 
    int secret_num; 
}; 

int main() 
{ 

    int index= -1; 
    Object *urobj = new Object(104); 
    std::vector<Object*> urvector; 

    for(int i = 0; i < 10; ++i) 
    { 
     Object *obj = new Object(i+1); 
     urvector.push_back(obj); 

    } 

    urvector.push_back(urobj); 

    for(int j = 0; j < urvector.size(); ++j) 
    { 
     Object *tmp = urvector.at(j); 
     std::cout << tmp->getSecretNum() << std::endl; 
     if(urobj == tmp) 
      index = j; 
    } 

    if(index == -1) 
     std::cout << " not match " << std::endl; 
    else 
     std::cout << " match " << index << std::endl; 

    return 0; 
} 

如果矢量支持平等的对象,这对去除条件 ,那么你可以使用:

v.erase(std::remove(v.begin(), v.end(), "ghi"), v.end()); 

否则,你需要remove_if,用功能对象(或lambda, 如果您有C++ 11),如果要删除该元素,则返回true。