2013-07-10 3 views
1

У меня есть следующий код для хранения объектов типа LVA в векторе. Я реализовал метод добавления объекта LVA к вектору. Первый вопрос: Можно ли использовать ссылку на объект LVA в этом методе?Удалить пользовательский объект из вектора

Теперь я хочу реализовать метод удаления объекта LVA. Я хочу иметь следующую подпись метода: void RemoveLVA(LVA& lva). Как я могу реализовать этот метод? Т.е. как я могу найти нужный объект в векторе, чтобы удалить его?

Manager.h

class Manager { 
public: 
    Manager(); 
    Manager(const Manager& orig); 
    virtual ~Manager(); 
    vector<LVA> GetLvas() const; 
    void AddLva(LVA& lva); 
private: 
    vector<LVA> lvas; 

}; 

Manager.cpp:

#include "Manager.h" 

Manager::Manager() { 
} 

Manager::Manager(const Manager& orig) { 
} 

Manager::~Manager() { 
} 

vector<LVA> Manager::GetLvas() const { 
    return lvas; 
} 

void Manager::AddLva(LVA& lva) { 
    lvas.push_back(lva); 
} 
+1

В обоих ваших конкретных случаях параметр 'const LVA & lva' делает подпись вашего кода более явной. – Chad

ответ

1

Это нормально, если я использую ссылку на объект LVA в AddLva (LVA & lva)?

Да, std::vector будет иметь копию вашего исходного объекта после push_back() завершения.

Как можно использовать RemoveLVA (LVA & lva)?

Вам нужно будет найти объект в вашем векторе. (Вы можете использовать std::find(), если operator==() определен для LVA.) Затем вызовите функцию erase() для вашего вектора.

+1

спасибо, поэтому правильный способ для этого подхода - переопределить оператор == в классе LVA? то я могу сделать что-то вроде 'if lvaToDelete == lvaInVector, а затем удалить его' – Moonlit

+0

@ user1291235 С помощью итераторов вы просто используете' lvas.erase (std :: find (lvas.begin(), lvas.end(), lva)) ' – chrisaycock

+1

@ user1291235 Возможно. Если '==' имеет смысл и имеет общепризнанную семантику для вашего объекта, то используйте его. Если определение эквивалентности специфично для этого контейнера, тогда было бы предпочтительнее определить функциональный объект для обработки этого случая. –

1

Это нормально, если я использовать ссылку на объект LVA в этом методе?

проблем нет. Фактически вы делаете копию с помощью операции push_back.

0

Ваш метод вставки прав, но не забывайте, что в вектор вставляется только копия вашего объекта LVA. это означает, что в методе RemoveLVA вам нужно будет использовать somthing как перегрузку operator== до std::find объекта вектора, который соответствует вашему параметру, а затем удаляет его.

Возможно, вы предпочитаете вставлять указатели или std::shared_ptr из LVA в свой вектор. Никакая копия объекта не будет происходить, и поиск объекта вернется к сравнению указателя, если вы сохраните указатель где-то еще в своей программе (2 объекта с тем же содержимым и разными стеками или ячейками кучи будут сравниваться с ложью) ,

+0

Почему он предпочел бы указатели? –

+1

@JamesKanze: Предположительно для полиморфизма, хотя об этом никто не упоминает. Тем не менее, я даю rems4e преимущество сомнений. –

+0

Нет копии, если он хочет только ссылаться на свои объекты, например. И правильно, Джон, я даже забыл об этом :) – rems4e

1

Не зная больше о LVA, это трудно быть точным, но вы, вероятно, хотите константную ссылку на AddLva, так как вы не изменяя его функции (и вы можете передать временный).

Для удаления: вы должны определить какой-то функции эквивалентности над LVA что вы хотите удалить соответствующий элемент.Это может быть LVA::operator== или какой-либо другой объект или функция : в первом случае вы используете std::find, чтобы найти положение , а во втором - std::find_if. Если вектор может содержать более одного подходящего элемента, вы можете посмотреть std::remove или std::remove_if.

0

Да, AddLva может взять ссылку, хотя, как правило, принимать const ссылка:

void Manager::AddLva(const LVA& lva) { 
    lvas.push_back(lva); 
} 

Заметим, однако, что если вы ожидаете, что ссылка добавляется в vector, это не делает, что , Составлена ​​копия объекта lva, и эта копия добавляется к вектору.

0

Да, это нормально передать объект LVA как ref в методе добавления и удаления. Вы также можете объявить эти параметры как «const», потому что я полагаю, что добавление и удаление не повлияют на объект.

для метода удалить

void RemoveLVA(const LVA& lva) 
{ 
    std::vector<LVA>::iterator position = 
    std::find(lvas.begin(), lvas.end(), lva); 
    if (position != lvas.end()) 
    { 
     lvas.erase(position); 
    } 
} 

но класса LVA должен иметь оператор ==.

удачи.

Смежные вопросы