2014-11-21 2 views
0

У меня есть класс Player, где каждый объект типа Class имеет имя, выигрыши, потери и рисунки. Каждый объект класса Player создается путем вызова the_player = new Player (the_name). Когда пользователь вводит новое имя для добавления объекта Player в программу, указатель вводится в вектор AllPlayers. Программа должна проверить перед нажатием нового указателя, что желаемый игрок еще не существует в указанном векторе. Я должен делать эту проверку несколько раз в течение всей своей программы, поэтому я решил написать для нее функцию. Вот моя функция:Поиск вектора указателей объектов

int findPlayer(vector<Player*> &vals, string name_in) 
{ 
    for (int i = 0; i < vals.size(); i++){ 
     if (vals[i]->getName() == name_in){ 
      cout << vals[i]->toString() << endl; 
      return i; 
     } 
     else 
      return -1; 
    } 
}; 

Когда опция предлагается добавить новый плеер следующий код используется:

do { 
    cout << "Name: "; 
    cin >> the_name; 

    if (findPlayer(AllPlayers, the_name) != -1){ 
     cerr << "Player already exists\n"; 
    } 
} while (findPlayer(AllPlayers, the_name) != -1); 

the_player = new Player(the_name); 
AllPlayers.push_back(the_player); 

По некоторым причинам, хотя, каждый раз, когда я пытаюсь добавить новый игрок он бросает «Player уже существует» и никогда не покидает цикл do-while. Это даже верно, когда вектор AllPlayers пуст. Я добавил cout < < findPlayer (AllPlayers, the_name) для отладки и напечатал 4192252, который, как я полагаю, является наибольшим элементом, возможным в векторе.

Итак, вопрос в том, почему он возвращает 4192252, а не -1?

+1

Вы включили предупреждения компилятора? Моя предупреждает об ошибке, которая вызывает это. – user2079303

+1

Прошли ли вы через свой код с помощью отладчика? –

ответ

0

Находку функция игрок должен быть что-то вроде:

int findPlayer(vector<Player*> &vals, string name_in) 
{ 
    if(vals.size() == 0) 
     return -1; 

    for (int i = 0; i < vals.size(); i++){ 
     if (vals[i]->getName() == name_in){ 
      cout << vals[i]->toString() << endl; 
      return i; 
     } 
    } 
    return -1; 
}; 
+0

Решает вопрос точно в 0%. Вы возвращаете -1, который все еще печатает ошибку. – Blacktempel

+0

@Blacktempel: Только если он не найден; если это так, 'return i' возвращает другое значение. Это правильно, хотя первоначальный тест бессмыслен. –

+0

Это решило это. Давая ему базовый случай, что в векторе не было ничего, что означало бы -1, что означало бы, что указанное имя не найдено в векторе, что было бы правильно. – Spencer

3

Что вы думаете, что будет возвращено из findPlayer, если vals пусто?

Определен?

+3

Даже если он указывает прямо на ответ, это должен быть комментарий. Добавьте объяснение для увеличения. – molbdnilo

+2

У меня нет репутации, чтобы комментировать. У меня должно быть 50. :) – Neska

4

Если vals пуст, цикл for никогда не вводится, и функция выходит, не нажимая оператор возврата. Это означает, что вы получаете вместо него случайное значение, в этом случае 4192252 находится в регистре возврата. Ваши предупреждения о компиляторе скажут вам это, если вы их прочтете.

+0

Я на Visual Studio 2013. Я должен предположить, что предупреждения включены, потому что я получаю много предупреждений все время (новое для C++), но на нем ничего не отображалось. – Spencer

+0

@Spencer Вы увидите [это предупреждение (C4715)] (http://msdn.microsoft.com/en-us/library/6deaf4k9.aspx), которое является предупреждением уровня 1 и поэтому должно отображаться на всех уровнях предупреждения , Вы должны начать компиляцию с помощью '/ WX' для обработки предупреждений как ошибок, если вы хотите, чтобы компилятор помог вам найти такие глупые вещи. – sjdowling

0

переписать функцию следующим образом

bool findPlayer(const std::vector<Player*> &vals, const std::string &name_in) 
{ 
    std::vector<Player*>::size_tyoe i = 0; 

    while (i < vals.size() && vals[i]->getName() != name_in) ++i; 

    return i != vals.size(); 
} 

Примите во внимание, что функция член getName должен быть определен с классификатором const.

Что касается вашей функции, то она ничего не возвращает в случае, когда вектор пуст или возвращает -1, если первый элемент вектора не совпадает со строкой.

Примите во внимание, что существует стандартный алгоритм std::find_if, объявленный в заголовке <algorithm>, который может использоваться вместо вашей функции.

1

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

В противном случае вы проверяете только первый элемент и немедленно возвращаете, соответствует ли он. Вы хотите вернуться, если найдете совпадение, но продолжайте искать иначе и возвращаете -1, если нет совпадения:

for (int i = 0; i < vals.size(); i++){ 
    if (vals[i]->getName() == name_in){ 
     cout << vals[i]->toString() << endl; 
     return i; 
    } 
} 
return -1; 
Смежные вопросы