通过值传递的C++向量:我做对了吗?

Flo*_*lla 5 c++ vector heap-memory

假设我有一个像这样的结构:

struct typeA
{
    long first;
    string second
    double third;
};
Run Code Online (Sandbox Code Playgroud)

如果我宣布

typeA myArray[100];
Run Code Online (Sandbox Code Playgroud)

然后myArray存储在堆栈中,消耗sizeof(typeA)*100字节的垃圾数据(直到我存储一些实际数据,至少).

每当我将这个数组作为参数传递时,我总是会将指针传递给堆栈中第一个元素.所以指针从堆栈到堆栈.

但是,如果我宣布

vector<int> myVector (4, 100);
Run Code Online (Sandbox Code Playgroud)

然后myVector对象实际存储在堆栈中,它包含一个指向存储在堆中的4*sizeof(int)字节数组的第一个元素的指针,存储实际数据.所以指针从堆栈转到堆栈.

每当我将此向量作为参数传递时,如果我将其添加到参数列表中,如下所示:

vector<int> parameterVector
Run Code Online (Sandbox Code Playgroud)

该函数获取myVector对象副本并将其存储在堆栈中.

但如果我这样做:

vector<int> &parameterVector
Run Code Online (Sandbox Code Playgroud)

该函数获取存储在堆栈中的myVector引用,因此我现在有一个存储在堆栈中的变量,引用一个也存储在堆栈中的myVector对象,它包含一个指向存储在堆中的实际元素数组的指针.

它是否正确?

我有点怀疑:

  1. 实际的元素是否存储在堆中的静态数组(从C继承的那些,用方括号表示)中?
  2. myVector对象是否只有一个指向第一个元素的指针,或者它有多个指向每个元素的指针?
  3. 因此,按值传递矢量并不会造成太大问题,因为复制的唯一内容是矢量对象,而不是实际元素.是这样吗?
  4. 如果我把整个事情弄错了,并且在按值传递矢量参数时也会复制实际元素,那么为什么C++允许这样做,考虑到它会阻止静态数组呢?(据我所知,静态数组总是作为对第一个元素的引用传递).

谢谢!

Nat*_*ica 2

实际元素是否存储在堆中的静态数组(从 C 继承的数组,用方括号表示)中?

通常,向量的元素使用动态数组存储在自由存储中,例如

some_type* some_name = new some_type[some_size]
Run Code Online (Sandbox Code Playgroud)

myVector 对象是否只有一个指向第一个元素的指针,还是有多个指向每个元素的指针?

通常,向量将具有指向第一个元素的指针、大小变量和容量。它可以有更多,但这些是实现细节,不是由标准定义的。

因此,按值传递向量不会造成太大问题,因为唯一被复制的是向量对象,而不是实际元素。是这样吗?

不,复制向量是一个 O(N) 操作,因为它必须复制向量的每个元素。如果没有,那么您将有两个向量使用相同的底层数组,如果一个向量被破坏,那么它将从另一个向量下删除该数组。

  • *“将其视为按值传递的对象”*,只不过修改它会影响函数外部的某些内容。 (3认同)