向量中的向量在第二维生成重复值

vector within vector generates duplicate values in second dimension

在下面的示例中(也可以在 Ideone 中看到),我有一个 class 的 vector 并且在 class 里面我有一个元素还有 vector.

问题在于,在执行 class 的 push_back 时,内部向量 vetint 应该重新从头开始,对于第一个 push_back维度,但 C++ 保留了以前的值,因此向量加倍。

#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

为什么会这样?如何解决?

如果您展开第一个 for 循环,您的代码将是:

classe obj;

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

// obj has three elements in it.
vetor.push_back(obj);

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

// obj has six elements in it.
vetor.push_back(obj);

这就解释了为什么 vetor 中第二个对象的 vetint 有六个元素。

您可以使用以下方法之一解决问题:

解决方案 1

obj 的 declaration/definition 移动到 for 循环中。

for (unsigned i=0; i<2 ; i++) {
    classe obj;
    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 的内容。

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

问题是,在您的第一个 push_back 之后,没有什么能让 obj.vetint 变空。将 obj 的范围收紧到循环。

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

您也可以明确删除 obj.vetint (obj.vetint.clear()) 的内容,所以您可以选择。收紧范围通常是首选,但如果您清除(您将避免每次循环迭代重新分配内存),在这种情况下会有轻微的性能提升。

在另一个 for 循环内的 for 循环中,您要将整数值插入到向量中。

第一次它会插入 {100, 200, 300} 然后 c 等于 3 。它退出内部 for 循环。 i 变为 2,然后进入内部 for 循环。 c 变为 0 。您再次将值插入到同一个向量中。因此矢量值将变为 { 100, 200, 300, 100, 200, 300} 。 在递增 i 值之前,您必须通过调用 vectorname.clear() 来清除矢量列表。