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

C++嵌套vector执行push_back时二维vector出现重复值的问题排查与解决

问题:C++中vector存储自定义类时,内层vector元素累积重复

我定义了一个存储自定义类classe的vector,这个类里包含一个vector<int>类型的成员vetint。现在遇到的问题是,每次给外层vector执行push_back操作时,我期望内层的vetint能重新初始化、从头添加元素,但实际它会保留之前的值,导致元素重复累积。

示例代码

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

class classe {
public:
    int var;
    vector<int> vetint;
};

int main() {
    vector<classe> vetor;
    classe obj;

    for (unsigned i=0; i<2 ; i++) {
        obj.var = (i+1)*10;
        for (unsigned c=0; c<3 ; c++) {
            obj.vetint.push_back((c+1)*100);
        }
        vetor.push_back(obj);
    }

    for (unsigned i=0; i < vetor.size() ; i++) {
        cout << "var(" << i << ") = " << vetor[i].var << endl;
        for (unsigned c=0; c < vetor[i].vetint.size() ; c++) {
            cout << "vetint(" << c << ") = " << vetor[i].vetint[c] << endl;;
        }
    }
}

当前执行结果

var(0) = 10
vetint(0) = 100
vetint(1) = 200
vetint(2) = 300
var(1) = 20
vetint(0) = 100
vetint(1) = 200
vetint(2) = 300
vetint(3) = 100
vetint(4) = 200
vetint(5) = 300

期望输出结果

var(0) = 10
vetint(0) = 100
vetint(1) = 200
vetint(2) = 300
var(1) = 20
vetint(0) = 100
vetint(1) = 200
vetint(2) = 300

请问这个问题产生的原因是什么?该如何解决?


解答

问题原因

你只创建了一个classe对象obj,在整个循环过程中反复修改它的成员,然后把它的副本添加到外层vector里。但每次循环时,你没有清空obj.vetint,而是在之前的基础上继续push_back新元素,所以第二次循环时,vetint已经保留了第一次的3个元素,再加上新的3个就变成了6个,这个带有6个元素的对象被复制到外层vector后,就出现了元素累积的情况。

简单来说:你的obj是在循环外创建的,它的vetint容器不会自动重置,每次循环都是往同一个容器里追加元素。

解决方法

有几种实用的解决方式,你可以根据自己的需求选择:

方案1:每次循环创建新的classe对象

把classe obj;移到外层循环内部,这样每次循环都会生成一个全新的对象,它的vetint自然是空的,每次都能从头添加元素:

int main() {
    vector<classe> vetor;

    for (unsigned i=0; i<2 ; i++) {
        classe obj; // 每次循环新建对象,vetint默认是空的
        obj.var = (i+1)*10;
        for (unsigned c=0; c<3 ; c++) {
            obj.vetint.push_back((c+1)*100);
        }
        vetor.push_back(obj);
    }

    // 输出部分保持不变
}

方案2:每次循环前清空obj.vetint

如果不想每次新建对象,可以在每次内层循环开始前,手动清空obj的vetint容器,确保每次都是从头添加元素:

int main() {
    vector<classe> vetor;
    classe obj;

    for (unsigned i=0; i<2 ; i++) {
        obj.var = (i+1)*10;
        obj.vetint.clear(); // 清空之前的元素,重置容器
        for (unsigned c=0; c<3 ; c++) {
            obj.vetint.push_back((c+1)*100);
        }
        vetor.push_back(obj);
    }

    // 输出部分保持不变
}

方案3:给类添加构造函数(更规范的写法)

给classe添加一个构造函数,确保每次创建对象时成员都处于初始状态(虽然vector的默认构造已经会生成空容器,但显式定义构造函数能让代码更清晰,也方便后续扩展):

class classe {
public:
    int var;
    vector<int> vetint;

    // 构造函数:初始化var为0,vetint默认是空容器
    classe() : var(0) {}
};

之后配合方案1使用,代码的可读性和规范性会更好。


内容的提问来源于stack exchange,提问作者Rogério Dec

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 07:48:04