Zud*_*Zud 269 c++ arrays vector
C++中的a std::vector和a有什么区别std::array?什么时候应该优先于另一个?各自的优点和缺点是什么?我的所有教科书都列出了它们是如何相同的.
Mat*_*lia 305
std::vector是一个模板类,它封装存储在堆中的动态数组1,如果添加或删除元素,它将自动增长和收缩.它提供了所有钩子(begin(),end()迭代器等),使其与STL的其余部分一起工作.它还有几个有用的方法,可以让你在普通数组上执行繁琐的操作,例如在向量中间插入元素(它处理在幕后移动后续元素的所有工作).
由于它将元素存储在堆上分配的内存中,因此它在静态数组方面有一些开销.
std::array是一个模板类,它封装了一个存储在对象本身内的静态大小的数组,这意味着,如果在堆栈上实例化该类,则数组本身将位于堆栈中.它的大小必须在编译时知道(它作为模板参数传递),并且它不能增长或缩小.
它比有限std::vector,但它通常更有效,特别是对于小尺寸,因为在实践中它主要是围绕C风格阵列的轻量级包装.但是,它更安全,因为禁用了对指针的隐式转换,并且它提供了许多与std::vector其他容器相关的STL相关功能,因此您可以轻松地将其与STL算法和co一起使用.无论如何,对于固定大小的限制,它的灵活性要小得多std::vector.
有关介绍std::array,请看一下这篇文章 ; 为了快速介绍std::vector和操作可能的操作,您可能需要查看其文档.
Clo*_*boy 15
使用std::vector<T>课程:
... 就像使用内置数组一样快,假设你只做内置数组允许你做的事情(读取和写入现有元素).
...插入新元素时自动调整大小.
...允许您在向量的开头或中间插入新元素,自动"移动"其余元素"向上"(这有意义吗?).它允许您删除元素中的任何元素std::vector,自动将其余元素向下移动.
...允许您使用该at()方法执行范围检查读取([]如果您不希望执行此检查,则可以始终使用索引器).
使用有两个主要注意事项std::vector<T>:
您没有对底层指针的可靠访问权限,如果您正在处理需要数组地址的第三方函数,这可能是一个问题.
这std::vector<bool>堂课很傻.它实现为压缩的位域,而不是数组.如果你想要一个bools 数组,请避免使用它!
在使用过程中,std::vector<T>s将比具有相同元素数量的C++数组大一点.这是因为他们需要跟踪少量其他信息,例如他们当前的大小,并且因为每当std::vector<T>调整大小时,他们都会保留更多的空间.这是为了防止它们每次插入新元素时都必须调整大小.这种行为可以通过提供自定义来改变allocator,但我从来没有觉得有必要这样做!
编辑:在阅读Zud对问题的回复后,我觉得我应该补充一下:
的std::array<T>类是不一样的,为C++阵列.std::array<T>是一个非常薄的C++数组包装器,其主要目的是将指针隐藏在类的用户之外(在C++中,数组被隐式地转换为指针,通常会产生令人沮丧的效果).所述std::array<T>类还存储它的大小(长度),其可以是非常有用的.
Mar*_*ata 14
为了强调@MatteoItalia提出的观点,效率差异是存储数据的地方.堆内存(需要vector)需要调用系统来分配内存,如果计算周期,这可能会很昂贵.堆栈存储器(可能array)在时间上实际上是"零开销",因为仅通过调整堆栈指针来分配存储器,并且在进入函数时仅执行一次.堆栈还避免了内存碎片.可以肯定的是,std::array并不总是在堆栈上; 它取决于你分配它的位置,但与vector相比,它仍然会减少堆中的内存分配.如果你有
绝对使用std::array一个矢量.如果这些要求中的任何一个不成立,那么使用a std::vector.
psi*_*son 11
如果您正在考虑使用多维数组,那么std :: array和std :: vector之间还有一个区别.多维std :: array将在所有维度中将元素打包在内存中,就像交流样式数组一样.多维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]
Run Code Online (Sandbox Code Playgroud)
指向c样式数组(cConc)或std :: array(aConc)中第一个元素的指针可以通过向每个前面的元素添加1来遍历整个数组.他们紧紧包装.
指向向量数组(vConc)或指针数组(ptrConc)中第一个元素的指针只能通过前5个(在本例中)元素迭代,然后有12个字节(在我的系统上)用于下一个矢量.
这意味着初始化为[3] [1000]数组的std :: vector>数组在内存中要小于作为[1000] [3]数组初始化的数组,并且内存中的数据都比std更大:数组分配方式.
这也意味着你不能简单地将一个多维向量(或指针)数组传递给openGL而不考虑内存开销,但是你可以天真地将多维std :: array传递给openGL并让它运行起来.
将上述讨论总结在一个表格中以供快速参考:
| C 样式数组 | 标准::数组 | 标准::向量 | |
|---|---|---|---|
| 尺寸 | 固定/静态 | 固定/静态 | 动态的 |
| 内存效率 | 更高效 | 更高效 | 效率较低 (可能会在新分配时将其规模加倍。) |
| 复印 | 迭代元素 或使用 std::copy() |
直接复制:a2 = a1; | 直接复制:v2 = v1; |
| 传递给函数 | 通过指针传递。 (功能中不提供尺寸) |
按值传递 | 按值传递 (该函数中可用的大小) |
| 尺寸 | sizeof(a1) / sizeof(a1[0]) | a1.size() | v1.size() |
| 用例 | 用于快速访问以及 不经常需要插入/删除时。 |
与经典数组相同,但 更安全、更容易传递和复制。 |
可能需要频繁添加或删除时 |