2012-08-02 96 views
1

我想刪除對象矢量中的元素。該向量填充了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

回答

6

如果你的用例沒有重複,那麼你最好使用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

4

如果你必須使用一個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

0
#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; 
} 
1

如果矢量支持平等的對象,這對去除條件 ,那麼你可以使用:

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

否則,你需要remove_if,用功能對象(或lambda, 如果您有C++ 11),如果要刪除該元素,則返回true。