设置者不更改类中向量的数据

Posted

技术标签:

【中文标题】设置者不更改类中向量的数据【英文标题】:Setter not changing the data from a vector within a class 【发布时间】:2019-04-07 21:07:59 【问题描述】:

在我的程序中,我有一个包含整数类型向量的类。它用于存储距离。我有一个函数,当调用它时,应该将向量中的值设置为 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 个值为 0 的槽(假设传递给函数的所需大小为 30),而不是一个空向量。

【问题讨论】:

是的,这就是您发布的代码的作用。因此,您看到的错误位于代码中的其他位置。您需要发布更多代码,尤其是检查向量大小的部分。很多时候(尤其是对于新手)错误不在他们认为的位置。 我把你的代码放到网上,cpp.sh/6d7aa。如您所见,它工作正常。 你是如何创建这个对象并在之后检查向量的? 在我的回答和提供的链接中,代码按照您的预期执行。有什么问题? @john 我用调用函数本身的位置更新了我的代码。我正在使用 qt,当我从 csv 文件中读取以存储所有输入时,它可能有点复杂。如果您能看一下,将不胜感激 【参考方案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);

【讨论】:

感谢您的回复,不幸的是,我的问题中省略了构造函数和析构函数,因为我认为这样的问题没有必要,但我的程序中确实有它们。它仍然没有保存 0 的 30 个值。我用我调用它的位置更新了我的问题,希望你仍然可以查看它并在那里找到我的错误! @OscarLopez 我更新了我的答案,我认为 atIndex() 返回元素的副本而不是对的引用 @OscarLopez 我编辑了我的答案以添加一个示例来解释 完美运行!非常感谢! @OscarLopez 可能您需要 2 个定义,即当前的(添加引用),以及另一个在 const returnint a const reference 的情况下的定义

以上是关于设置者不更改类中向量的数据的主要内容,如果未能解决你的问题,请参考以下文章

使用类中的值设置等于新值而不更改先前值c ++

如何使用方法更改指针?

将无符号字符附加到向量会更改其值

R语言使用names函数为向量vector中的所有数据对象设置名称使用names函数查看向量中所有数据的名称

Visual Studio 的 C++ 调试 - 向量大小变化的观察点

使用设置属性 (DOM) 更改操作值