Сеттер не меняет данные из вектора внутри класса

В моей программе есть класс, содержащий вектор целого типа. Он используется для хранения расстояний. У меня есть функция, которая при вызове должна устанавливать значения в векторе равными 0. (используется для инициализации). Но когда я иду, чтобы проверить размер вектора, он все еще говорит, что вектор пуст.

Я создал несколько функций, которые проверяют, добавляет ли вектор какие-либо элементы, и это не так. У меня есть функция, которую в main я вызываю, чтобы увидеть, пуст ли вектор, и она возвращает 0 (в векторе 0 элементов).

int MLB::getDistanceSize()
{
    return distances.size();
}

void MLB::setInitialDistances(int size)
{
    for(int i = 0; i < size; i++)
    {
        this->distances.push_back(0);
    }
}
class MLB
{
public:
    //constructor
    MLB();
    ~MLB();

    int getDistanceSize();
    void setInitialDistances(int size);

private:
    vector<int> distances;
};

Входной файл представляет собой файл csv, каждая строка которого состоит из:

стадион1,стадион2,расстояние

поэтому пример входного файла:

AT&T Park,Safeco Field,680
AT&T Park,Oakland–Alameda County Coliseum,50
Angel Stadium,Petco Park,110
Angel Stadium,Dodger Stadium,50
Busch Stadium,Minute Maid Park,680
Busch Stadium,Great American Ball Park,310
Busch Stadium,Target Field,465
Busch Stadium,Kauffman Stadium,235

и т.д...

Я использую qt, и здесь я вызываю сами функции. Вся информация хранится в карте, и другие геттеры работают отлично. Извините, что сделал это намного более запутанным, чем проблема на самом деле, любая помощь очень ценится.

// key and value, key is the team name, value is the MLB stadium information
struct entry
{
    string key;
    MLB value;
};

class Map
{
    public:
        //Public default constructor
        Map();

        //Public default destructor
        ~Map();

        // returns entry of the map
        entry atIndex(int index);

        // Inserts a key and its value using linear algorithm
        void insert(const string& theKey, const MLB& value);

    private:

    vector<entry> thisTable;
    int currentSize;    //Integer variable for current size
};

функции для карты:

Map::Map()
{
    currentSize = 0;
}

Map::~Map()
{
}

void Map::insert(const string& theKey, const MLB& value)
{
    entry thisEntry;
    thisEntry.key = theKey;
    thisEntry.value = value;

    thisTable.push_back(thisEntry);

    currentSize+=1;
}

entry Map::atIndex(int index)
{
    return thisTable.at(index);
}
//mainwindow constructor
mainWindow::mainWindow()
{

    //Reads in input from first csv file, all works fine all data stored and can access it

    string iStadium1;
    string iStadium2;
    string iDistance;
    string previous;
    int distance;
    int index1;
    int index2;
    bool found;

    ifstream csvFile2;
    csvFile2.open("inputDistance.csv");

    getline(csvFile2, iStadium1, ',');
    while(!csvFile2.eof())
    {
        index1 = 0;
        found = false;
        while(!found)
        {
            if(thisMap.atIndex(index1).value.getStadiumName() == iStadium1)
            {
                thisMap.atIndex(index1).value.setInitialDistances(thisMap.mapSize());
                cout << "Distance Size Test 1: " << thisMap.atIndex(index1).value.getDistanceSize() << endl;
                found = true;
            }
            else
            {
                index1++;
            }
        }

        previous = iStadium1;

        while(iStadium1 == previous)
        {
            getline(csvFile2, iStadium2, ',');
            getline(csvFile2, iDistance, '\n');
            distance = stoi(iDistance);

            index2 = 0;
            found = false;

            while(!found)
            {
                if(thisMap.atIndex(index2).value.getStadiumName() == iStadium2)
                {
                    found = true;
                    cout << "Distance Size Test 2: " << thisMap.atIndex(index1).value.getDistanceSize() << endl;
                    // crashes here. Index out of bounds, size is 0 for some reason
                    thisMap.atIndex(index1).value.setDistance(index2, distance);
                }
                else
                {
                    index2++;
                }
            }
            getline(csvFile2, iStadium1, ',');
        }
    }

    csvFile2.close();
}

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


person Oscar Lopez    schedule 07.04.2019    source источник
comment
Да, это то, что будет делать код, который вы разместили. Таким образом, ошибка, которую вы видите, находится где-то еще в вашем коде. Вам нужно опубликовать больше кода, особенно ту часть, где вы проверяете размер вектора. Очень часто (особенно у новичков) ошибка оказывается не там, где они думают.   -  person john    schedule 08.04.2019
comment
Я взял ваш код и разместил его в Интернете, cpp.sh/6d7aa. Как видите, работает корректно.   -  person john    schedule 08.04.2019
comment
Как вы создаете этот объект и потом проверяете вектор?   -  person Cruz Jean    schedule 08.04.2019
comment
код делает то, что вы ожидали, в моем ответе и в предоставленной ссылке. В чем проблема ?   -  person bruno    schedule 08.04.2019
comment
@john Я обновил свой код, указав, где я вызываю саму функцию. Я использую qt, и это может быть немного сложно, так как я читаю из CSV-файла для хранения всех входных данных. Если бы вы могли взглянуть на это, было бы очень признательно   -  person Oscar Lopez    schedule 08.04.2019
comment
@OscarLopez Я предполагаю, что вы имеете дело с двумя разными объектами. Поэтому, когда вы вызываете thisMap.atIndex(index1).value, вы не получаете каждый раз один и тот же объект.   -  person john    schedule 08.04.2019
comment
@John, мне это странно, потому что, когда я вызываю thisMap.atIndex(index1).value.getStadiumName(), он правильно дает мне название стадиона. Это означает, что я нахожусь на правильном объекте, но это не сохранит информацию в векторе. Вектор - единственный, который не спасет   -  person Oscar Lopez    schedule 08.04.2019
comment
@OscarLopez Нужно посмотреть, как определяются thisMap и atIndex.   -  person john    schedule 08.04.2019
comment
@OscarLopez Это ничего не доказывает. Вы получаете копии своих объектов, поэтому название стадиона копируется правильно, но когда вы что-то меняете, изменяется только эта конкретная копия, а не копия, которую вы получите при следующем вызове atIndex.   -  person john    schedule 08.04.2019
comment
@OscarLopez Если вы опубликуете код для atIndex, я надеюсь, что это можно быстро прояснить.   -  person john    schedule 08.04.2019
comment
@OscarLopez Хорошо, поменяй на это entry& Map::atIndex(int index) { return thisTable.at(index); }   -  person john    schedule 08.04.2019
comment
@john Я обновил свой код для atIndex   -  person Oscar Lopez    schedule 08.04.2019
comment
@OscarLopez Как я и думал, atIndex не возвращает запись на вашей карте, она возвращает копию записи на вашей карте. Измените его, чтобы вернуть ссылку (см. два комментария выше).   -  person john    schedule 08.04.2019
comment
@john, я думаю, что он такой же, и приведу пример в свой ответ   -  person bruno    schedule 08.04.2019
comment
@john Теперь это работает как шарм. Большое спасибо! Я занимался этим около 6 часов и решил просто спросить здесь.   -  person Oscar Lopez    schedule 08.04.2019
comment
@OscarLopez, это очень запутанная проблема, когда она возникает впервые.   -  person john    schedule 08.04.2019


Ответы (1)


Код в вашем вопросе работает, как и ожидалось, после добавления конструктора и деструктора (ничего не делая):

#include <iostream>
#include <vector>
using namespace std;

class MLB
{
public:
    //constructor
    MLB();
    ~MLB();

    int getDistanceSize();
    void setInitialDistances(int size);

private:
    vector<int> distances;
};

int MLB::getDistanceSize()
{
    return distances.size();
}

void MLB::setInitialDistances(int size)
{
    for(int i = 0; i < size; i++)
    {
        this->distances.push_back(0);
    }
}

MLB::MLB() {
}

MLB::~MLB() {
}


int main()
{
  MLB mlb;

  mlb.setInitialDistances(30);
  cout << mlb.getDistanceSize() << endl;
}

pi@raspberrypi:/tmp $ g++ d.cc
pi@raspberrypi:/tmp $ ./a.out
30

вектор не пуст, но содержит 30 раз 0


если thisMap.atIndex(index1).value.setDistance(index2, distance); ничего не делает, это, вероятно, потому, что atIndex(index1) возвращает копию, а не ссылку, поэтому вы изменяете копию, а оригинал остается неизменным

Например :

#include <iostream>
#include <vector>
using namespace std;

class C {
  public:
    vector<int> getv() { return v; } // return a copy
    vector<int> & getvref() { return v; } // return the ref to the vector, not a copy
    int len() { return v.size(); }

  private:
    vector<int> v;
};

int main()
{
  C c;

  c.getv().push_back(0); // modify a copy of v
  cout << c.len() << endl;

  c.getvref().push_back(0); // modify v
  cout << c.len() << endl;
}

Компиляция и исполнение:

pi@raspberrypi:/tmp $ g++ vv.cc
pi@raspberrypi:/tmp $ ./a.out
0
1

вы отредактировали свой вопрос, и это то, что я предполагал:

entry Map::atIndex(int index)
{
    return thisTable.at(index);
}

вернуть копию, должен быть

entry & Map::atIndex(int index)
{
    return thisTable.at(index);
}
person bruno    schedule 07.04.2019
comment
Спасибо за ваш ответ, к сожалению, я не учел конструктор и деструктор в своем вопросе, потому что думал, что в этом нет необходимости, но они есть в моей программе. Он по-прежнему не сохраняет 30 значений 0. Я обновил свой вопрос, указав, где я его называю, надеюсь, вы все еще можете взглянуть на это и найти там мою ошибку! - person Oscar Lopez; 08.04.2019
comment
@OscarLopez Я обновил свой ответ, я думаю, что atIndex() возвращает копию элемента, а не ссылку на - person bruno; 08.04.2019
comment
@OscarLopez Я отредактировал свой ответ, добавив пример для объяснения - person bruno; 08.04.2019
comment
Работает отлично! Большое спасибо! - person Oscar Lopez; 08.04.2019
comment
@OscarLopez, вероятно, вам понадобится 2 определения: текущее (добавление ссылки) и другое в случае, если const возвращает ссылку на константу. - person bruno; 08.04.2019