You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

尝试将vector作为类成员传递引用,为何实际是传值导致修改无效?

问题:类中操作vector副本而非原容器的原因与解决办法

我尝试将vector作为类成员以引用传递,但实际是传值传递。编写的类中Swap_up方法用于修改vector元素位置,执行时类内打印显示元素已上移,但main函数中原vector的元素回到初始位置,操作的是副本而非原容器,请问哪里出错了?

原代码:

#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;
}

错误原因:

你类中的chart成员是值类型的vector容器,不是引用或指针。构造函数里的chart(arr)是调用vector的拷贝构造函数,把传入的原vector完整复制了一份到类成员里——相当于类操作的是原vector的"双胞胎副本",所有修改只在副本上生效,原vector自然不会有变化。

另外提个小问题:原代码中Swap_up里的x = y - 1;是逻辑错误,应该写成x = x - 1;,否则移动后x的位置会乱掉。

解决办法

办法1:把类成员改成引用类型

直接让类成员绑定到原vector的引用,这样所有操作都会直接作用在原容器上:

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) {
}

注意:要保证原vector的生命周期比类对象长,否则会出现悬空引用,导致程序崩溃。

办法2:把类成员改成指针类型

如果担心生命周期问题,用指针持有原vector的地址也是可行的:

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) {
}

然后修改Swap_up里的访问方式,把.改成->或者先解引用指针:

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 = x - 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;
}

内容的提问来源于stack exchange,提问作者b23

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.08 15:50:15