简体   繁体   中英

Reference to vector as class member

I tried to pass a vector as a class member by reference but I seem to have passed it by value.

So I am making a class that has a function that can change the position of an element in a vector. The code looks like this.

#include <iostream>
#include <string>
#include <vector>

using namespace std;

class Example {
    int x, y;
    vector<vector<string>> chart;
public:

    Example(int i, int j, vector<vector<string>>& arr);
    void Swap_up();
};

Example::Example(int i, int j, vector<vector<string>>& arr) :x(i), y(j), chart(arr) {
}

void Example::Swap_up() {
    if (x - 1 >= 0 && chart[x - 1][y].at(0) == ' ') {
        string temp = chart[x-1][y];
        chart[x - 1][y] = chart[x][y];
        chart[x][y] = temp;
        x = y - 1;
        for (int i = 0; i < chart.size(); i++) {
            for (int j = 0; j < chart[0].size(); j++) {
                cout << '[' << chart[i][j] << ']';
            }
            cout << endl;
        }
        cout << endl;
    }
    else
        cout << "Invalid move" << endl;

}




int main() {

    int chart_height;
    int chart_width;
    cout << "Enter height of the chart in number of spaces (Minimum number of spaces is 7)" << endl;
    cin >> chart_height;
    cout << "Enter width of the chart in number of spaces (Minimum number of spaces is 7)" << endl;
    cin >> chart_width;


    vector<vector<string>> chart; 
        chart.resize(chart_height);
    for (int i = 0; i < chart_height; i++)
        chart[i].resize(chart_width);

    for (int i = 0; i < chart_height; i++) {
        for (int j = 0; j < chart_width; j++) {
            if (chart[i][j] == "")
                chart[i][j].insert(0, 3, '  ');
        }
    }



    chart[6][5] = "EXA"; 
    for (int i = 0; i < chart_height; i++) { 
        for (int j = 0; j < chart_width; j++) {
            cout << '[' << chart[i][j] << ']';
        }
        cout << endl;
    }
    cout << endl;


    Example Exa1(6, 5, chart); 
    Exa1.Swap_up();


    for (int i = 0; i < chart_height; i++) {
        for (int j = 0; j < chart_width; j++) {
            cout << '[' << chart[i][j] << ']';
        }
        cout << endl;
    }

    chart.clear();
    chart.resize(0);

    return 0;
}

I thought I had used a reference to the vector as a member of my class. So I had the program print the chart with the element in its original position and then execute swap_up, so the class method moves the element up a space and prints the chart again. This worked.

The problem is that then I had the program print the chart a third time and the element was back in its original position. So I obviously passed the vector as a class member by value and not by reference, so the class method didn't actually change the chart but a copy of it. What did I do wrong?

I thought I had used a reference to the vector as an attribute of my class.

No. You passed a reference to a vector as a parameter to your class's constructor. That's all you did.

Your constructor assigned it to its class member. It is very important to use correct terminology when discussing C++. C++ is complicated enough so that inconsistent terminology often leads to confusion.

vector<vector<string>> chart;

This is a commonly described as a class member, not an "attribute".

As you can see, it is not a reference. It is a discrete object. This means that when the constructor initializes the class member

... chart(arr)

the referenced vector gets copied into chart , a discrete object.

Subsequent changes to chart have no effect on the vector that was passed, by reference, to the constructor. After all, why should it? It's a vector, on its own merits.

If your expectations were that the original vector should be affected then the class member, itself, should be a reference:

class Example {
    int x, y;
    vector<vector<string>> &chart;

Then, the chart reference gets initialized from the reference to the parameter that gets passed to the constructor, and subsequent changes to chart reference that vector.

This kind of design is problematic for other reasons, generally, but they are immaterial to the question.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM