2016-02-09 6 views
0

Объекты, созданные мной для класса Player, не изменяют частную переменную, даже если она работает в функции, которая ее изменяет. Там могут быть некоторые проблемы с ссылкой на объекты, используемые в функции main(), но я не могу понять, где и почему.Объект C++ не сохраняет значение

В частности, петля в конце основного файла печатает игры, выигранные игроками в векторе Players, но все баллы возвращают 0. Так, когда функция плеера object.matchWon() правильно разобрать и распечатать счет и показывает изменения, внесенные в частная переменная.

Я подозреваю, что есть проблемы с использованием функции getPlayer() в главном коде.

Спасибо заранее!

Player.cpp:

#include "Player.h" 
#include <stdlib.h> 
#include <iostream> 

using namespace std; 
//constructor 
Player::Player(string first, string last) { 
    Player::first = first; 
    Player::last = last; 
    gWins = 0; 
    gLoss = 0; 
    mWins = 10; 
    mLoss = 2; 
} 

//setters 
void Player::addLoss(int increment) { 
    this->gLoss+=increment; 
} 

void Player::addWins(int increment) { 
    this->gWins+=increment; 
} 

void Player::matchWon(vector<string> scores) { 
    for (int i = 5;i<scores.size()-1;i++){ 
     cout<<(int)scores[i][0]-'0'<<"-"; 
     cout<<(int)scores[i][2]-'0'<<endl; 
     gWins+=scores[i][0]-'0'; //add games won 
     cout<<gWins<<endl; 
     gLoss+=(int)scores[i][2]-'0'; //add games lost 
    } 
    this->mWins++; 
} 

void Player::matchLost(vector<string> scores) { 
    this->mLoss++; 
} 

double Player::winPercentage() { 
    return (double)mWins/mLoss; 
} 

//accessors 
string Player::getFirstname() { 
    return this->first; 
} 

string Player::getLastname() { 
    return this->last; 
} 

int Player::getGameswon() { 
    //cout<<gWins; 
    return this->gWins; 
} 

main.cpp:

#include <iostream> 
#include "player.h" 
#include <fstream> 
#include <vector> 
#include <sstream> 

using namespace std; 

vector<string> split(const string &s) { 
    vector<string> elems; 
    istringstream iss(s); 
    do 
    { 
     string sub; 
     iss >> sub; 
     elems.push_back(sub); 

     //cout << "Substring: " << sub << endl; 

    } while (iss); 

    return elems; 
} 

Player &getPlayer(vector<Player> &players, const string &first, const string &last){ 
    for (int i=0;i<players.size();i++){ 
     if (players[i].getFirstname()==first&&players[i].getLastname()==last){ 
      return players[i]; 
     } 
    } 
    players.push_back(Player(first,last)); 
    return (players[players.size()-1]); 
} 

int main(int argc, char *argv[]) { 

    ifstream file(argv[1]); 
    ofstream ofile(argv[2]); 
    if (!file.is_open()){ 
     cerr <<"Could not open file\n"; 
     return 0; 
    } 

    string line; 
    vector<Player> players; 

    while (getline(file,line).good()){ 

     vector<string> lineParsed = split(line); 
     vector<string> matchData = split(line); 

     Player p1 = getPlayer(players,lineParsed[0],lineParsed[1]); 
     Player p2 = getPlayer(players,lineParsed[3],lineParsed[4]); 

     p1.matchWon(lineParsed); 
     cout<<p1.getFirstname()<<"!"<<p1.getGameswon()<<endl; 
    } 

    for (int i=0;i<players.size();i++){ 
     //cout<<players.size(); 
     cout<<players[i].getFirstname()<<":"<<players[i].getGameswon()<<endl; 
    } 


    return 0; 
} 
+1

Посмотрите этот ответ http://stackoverflow.com/questions/19608535/passing-a-vector-by-reference-to-function-but-change-doesnt-persist –

ответ

2

Вы копирование ваших игроков:

Player p1 = getPlayer(players,lineParsed[0],lineParsed[1]); 
Player p2 = getPlayer(players,lineParsed[3],lineParsed[4]); 

поэтому, когда вы p1.matchWon(), это происходит с местным Player объекта, а не один в векторе.

Хотя тип возврата getplayer() равен Player&, это не имеет значения, если вы назначаете его переменной без ссылки. Если вы хотите, чтобы модифицировать Player экземпляры в векторе, вы должны иметь

Player& p1 = getPlayer(players,lineParsed[0],lineParsed[1]); 
Player& p2 = getPlayer(players,lineParsed[3],lineParsed[4]); 

Кстати, getPlayer() небезопасно. Вектор может быть изменен, если вы используете push_back, недействительные ссылки. Вместо этого вы можете захотеть сохранить вектор указателей (или просто убедитесь, что, например, resize(), что вектор определенно имеет место для всех игроков, которых вы хотите нажать на него).

+0

Благодарим за отзыв! Когда вектор изменяет размер, он может изменить внутренние ссылки для хранимых переменных? это то, что вы имеете в виду, ссылаясь на ссылки? – youngin123

+0

Содержимое вектора может перемещаться в другое место памяти. См. [Этот вопрос] (http://stackoverflow.com/questions/8261037/what-happen-to-pointers-when-vectors-need-more-memory-and-realocate-memory) для специфики. – alcedine

+0

С уважением, спасибо – youngin123

0

Это поможет, если вы включили определение класса. Кажется, что-то странное происходит:

Player::first = first; 
Player::last = last; 

Являются ли эти статические поля? Если это так, проблема заключается в том, что вы сохраняете только первый и последний (имена?) Последнего созданного вами игрока.