在循环内构建向量并在该范围外构建 return 的安全方法?
Safe way to construct a vector inside a loop and return it outside that scope?
我有一个代码示例,我想请您检查一下并告诉我我的理解是否正确。我正在学习 C++,所以如果这些问题很初级,我深表歉意。我读过 C++ 如何处理内存管理,但我还没有找到实际的例子。我正在尝试自己写一些。
代码示例:
std::vector<std::vector<int32_t>> containerOfVectors;
for (int i = 0; i < 2; i++) {
std::vector<int32_t> innerVector;
innerVector.push_back(1);
containerOfVectors.push_back(move(innerVector));
innerVector.push_back(2);
innerVector.push_back(3);
innerVector.push_back(4);
std::cout << "innerVector " << std::to_string(i) << " contains: " << std::endl;
for (int k = 0; k < innerVector.size(); k++) {
std::cout << "\t" << std::to_string(innerVector[k]) << std::endl;
}
}
for (int i = 0; i < 2; i++) {
std::vector<int32_t> vector = containerOfVectors[i];
std::cout << "Vector " << std::to_string(i) << " contains " << std::to_string(vector.size()) << " element(s)" << std::endl;
}
----------
Output:
----------
innerVector 0 contains:
2
3
4
innerVector 1 contains:
2
3
4
Vector 0 contains 1 element(s)
Vector 1 contains 1 element(s)
我有一个向量的(容器)向量,我正在循环并在循环内创建两个向量,它们被添加到 containerOfVectors
。我将一个元素添加到循环内的向量,将其移动到 containerOfVectors
,然后再添加三个元素。
在第二个循环中,当我迭代 containerOfVectors
并打印出值时,我只看到 1
。值 2
、3
和 4
不存在。
我对此的理解是 move
调用将 innerVector
的元素复制到一个新向量中,此时 innerVector
变为空。因此,在循环迭代结束时,innerVector
将只包含 2、3 和 4,因为只有 1 被移动了。然后 innerVector
被销毁。
那一步实际上是“复制”,还是“移动”了相同的“2”?如果值是一个结构而不是一个整数,它会(或者它会怎样)不同吗?我怎样才能自己测试呢?通过打印内存地址,或者同一底层实例的内存地址可以不同吗?
很抱歉这里有很多东西要打开。非常感谢任何指导。
移动语义创建新对象。它不是副本或赋值,它是一个被调用的移动构造函数。因此,如果您调用 move(innerVector)
,您实际上会创建一个新的矢量对象作为 containerOfVectors 中的条目。这会在您拨打电话时自动包含原始 innerVector
的 content/data。之后,innerVector 为空,无论您对它做什么都不会影响 containerOfVectors 中的新对象。这两个不同的对象之间没有 link。 move-construction创建的对象的内存地址肯定和原来的对象不一样
这充分解释了示例的输出。对于向量中的任何其他数据类型,也包括结构,这将是相同的。
我有一个代码示例,我想请您检查一下并告诉我我的理解是否正确。我正在学习 C++,所以如果这些问题很初级,我深表歉意。我读过 C++ 如何处理内存管理,但我还没有找到实际的例子。我正在尝试自己写一些。
代码示例:
std::vector<std::vector<int32_t>> containerOfVectors;
for (int i = 0; i < 2; i++) {
std::vector<int32_t> innerVector;
innerVector.push_back(1);
containerOfVectors.push_back(move(innerVector));
innerVector.push_back(2);
innerVector.push_back(3);
innerVector.push_back(4);
std::cout << "innerVector " << std::to_string(i) << " contains: " << std::endl;
for (int k = 0; k < innerVector.size(); k++) {
std::cout << "\t" << std::to_string(innerVector[k]) << std::endl;
}
}
for (int i = 0; i < 2; i++) {
std::vector<int32_t> vector = containerOfVectors[i];
std::cout << "Vector " << std::to_string(i) << " contains " << std::to_string(vector.size()) << " element(s)" << std::endl;
}
----------
Output:
----------
innerVector 0 contains:
2
3
4
innerVector 1 contains:
2
3
4
Vector 0 contains 1 element(s)
Vector 1 contains 1 element(s)
我有一个向量的(容器)向量,我正在循环并在循环内创建两个向量,它们被添加到 containerOfVectors
。我将一个元素添加到循环内的向量,将其移动到 containerOfVectors
,然后再添加三个元素。
在第二个循环中,当我迭代 containerOfVectors
并打印出值时,我只看到 1
。值 2
、3
和 4
不存在。
我对此的理解是 move
调用将 innerVector
的元素复制到一个新向量中,此时 innerVector
变为空。因此,在循环迭代结束时,innerVector
将只包含 2、3 和 4,因为只有 1 被移动了。然后 innerVector
被销毁。
那一步实际上是“复制”,还是“移动”了相同的“2”?如果值是一个结构而不是一个整数,它会(或者它会怎样)不同吗?我怎样才能自己测试呢?通过打印内存地址,或者同一底层实例的内存地址可以不同吗?
很抱歉这里有很多东西要打开。非常感谢任何指导。
移动语义创建新对象。它不是副本或赋值,它是一个被调用的移动构造函数。因此,如果您调用 move(innerVector)
,您实际上会创建一个新的矢量对象作为 containerOfVectors 中的条目。这会在您拨打电话时自动包含原始 innerVector
的 content/data。之后,innerVector 为空,无论您对它做什么都不会影响 containerOfVectors 中的新对象。这两个不同的对象之间没有 link。 move-construction创建的对象的内存地址肯定和原来的对象不一样
这充分解释了示例的输出。对于向量中的任何其他数据类型,也包括结构,这将是相同的。