在C ++中,a std::vector
和an 有什么区别std::array
?什么时候应该优先于另一个?各自的优缺点是什么?我教科书所做的只是列出它们的相同之处。
std::array
与C ++数组不同。std::array
是围绕C ++数组的非常薄的包装器,其主要目的是向类用户隐藏指针。我将更新我的答案。
在C ++中,a std::vector
和an 有什么区别std::array
?什么时候应该优先于另一个?各自的优缺点是什么?我教科书所做的只是列出它们的相同之处。
std::array
与C ++数组不同。std::array
是围绕C ++数组的非常薄的包装器,其主要目的是向类用户隐藏指针。我将更新我的答案。
Answers:
std::vector
是一个模板类,封装了存储在堆中的动态数组1,如果添加或删除元素,该数组会自动增长和收缩。它提供了所有的钩子(begin()
,,end()
迭代器等),使其与STL的其余部分正常工作。它还有几种有用的方法,可让您执行在普通数组上比较麻烦的操作,例如在向量中间插入元素(它处理将以下元素移到幕后的所有工作)。
由于它将元素存储在分配给堆的内存中,因此相对于静态数组,它具有一些开销。
std::array
是一个模板类,封装了一个静态大小的数组,该数组存储在对象本身内部,这意味着,如果在堆栈上实例化该类,则数组本身将在堆栈上。它的大小必须在编译时就知道(作为模板参数传递),并且不能增长或缩小。
它比限制更多std::vector
,但通常效率更高,尤其是对于小尺寸,因为实际上它主要是围绕C样式数组的轻量级包装。但是,由于禁用了对指针的隐式转换,并且它提供了std::vector
和其他容器的许多STL相关功能,因此它更加安全,因此您可以轻松地将其与STL算法和co一起使用。无论如何,由于固定大小的局限性,它的灵活性远小于std::vector
。
作为介绍std::array
,看一下这篇文章 ; 有关其std::vector
可能的操作的快速介绍和操作,您可能需要查看其文档。
static
C ++中的very 关键字具有三种不相关的含义,该术语还经常用于谈论在编译时固定的内容。我希望“静态大小”更清晰一些。
使用std::vector<T>
类:
…… 就像使用内置数组一样快,假设您仅在执行内置数组允许的操作(对现有元素进行读写)。
...在插入新元素时自动调整大小。
...允许您在向量的开头或中间插入新元素,自动将其余元素“向上”移位(这有意义吗?)。它还允许您删除中的任意位置的元素std::vector
,从而自动将其余元素向下移动。
...允许您使用该at()
方法执行范围检查的读取([]
如果您不希望执行此检查,则可以始终使用索引器)。
有2点使用三种主要的注意事项std::vector<T>
:
您没有对基础指针的可靠访问,如果要处理需要数组地址的第三方函数,则可能会遇到问题。
这个std::vector<bool>
班很傻。它实现为压缩位域,而不是数组。如果您想要一个bool
s 数组,请避免使用它!
在使用期间,std::vector<T>
s将比具有相同数量元素的C ++数组大一些。这是因为它们需要跟踪少量其他信息,例如它们的当前大小,并且因为每当std::vector<T>
调整大小时,它们都会保留所需的更多空间。这是为了防止每次插入新元素时都必须调整它们的大小。可以通过提供一个custom来更改此行为allocator
,但是我从来没有觉得需要这样做!
编辑:在阅读Zud对问题的答复后,我觉得我应该添加以下内容:
的std::array<T>
类是不一样的,为C ++阵列。std::array<T>
是围绕C ++数组的非常薄的包装器,其主要目的是向类用户隐藏指针(在C ++中,数组隐式转换为指针,通常会产生令人沮丧的效果)。所述std::array<T>
类还存储它的大小(长度),其可以是非常有用的。
data()
a std::vector<T>
获取基础指针。您也可以只获取元素0的地址(保证与C ++ 11一起使用,可能会与早期版本一起使用)。
为了强调@MatteoItalia提出的观点,效率差异是数据的存储位置。堆内存(需要使用vector
)需要调用系统来分配内存,如果要计算周期,这可能会很昂贵。堆栈内存(可能是array
)在时间上实际上是“零开销”,因为仅通过调整堆栈指针即可分配内存,并且在输入函数时只需执行一次即可。堆栈还避免了内存碎片。可以肯定的是,std::array
不会总是出现在堆栈中。它取决于分配它的位置,但是与向量相比,它仍然会减少堆中的内存分配。如果你有一个
绝对使用std::array
一个向量。如果这些要求中的任何一项都不成立,请使用std::vector
。
new std::array
或使其成为您使用'new`进行分配的类的成员。
new std::array
仍然希望在编译时知道其大小,并且无法更改其大小,但仍驻留在堆中吗?
new std::array
vs 没有明显的优势new std::vector
。
如果您正在考虑使用多维数组,则std :: array和std :: vector之间还有另外一个区别。多维std :: array会将元素包装在所有维度的内存中,就像ac样式数组一样。多维std :: vector不会在所有维度上打包。
给出以下声明:
int cConc[3][5];
std::array<std::array<int, 5>, 3> aConc;
int **ptrConc; // initialized to [3][5] via new and destructed via delete
std::vector<std::vector<int>> vConc; // initialized to [3][5]
可以在c样式数组(cConc)或std :: array(aConc)中的第一个元素的指针遍历整个数组,方法是在每个元素前面加上1。他们被紧密包装。
指向向量数组(vConc)或指针数组(ptrConc)中第一个元素的指针只能在前5个(在这种情况下)元素中进行迭代,然后在我的系统上有12个字节的开销下一个向量。
这意味着初始化为[3] [1000]数组的std :: vector>数组将比初始化为[1000] [3]数组的std :: vector>数组小得多,并且两者在内存中都将比std大:数组以任何一种方式分配。
这也意味着您不能在不考虑内存开销的情况下简单地将多维矢量(或指针)数组传递给openGL,但是您可以将一个多维std :: array天真地传递给openGL并使其工作。
std::vector
vs.std::array
以及术语之间的差异。