使用数组而不是容器可以更有效地完成什么(如果有的话)?
我最近了解了C ++标准容器类。它们具有明显的优势并解决了C风格阵列的常见问题。关于“为什么阵列是邪恶的”的FAQ列表可以像这样松散地概括:
1. subscripts are not checked 2. often it is required to allocate memory from the heap 3. not easy to insert elements in the middle 4. always passed as reference
我想有很多情况,人们可以忍受这些缺点。但是,我对这个问题感到有些困惑,使用数组而不是容器可以更有效/更容易地完成什么?或者实际上没有这样的东西,我真的不应该关心数组了吗?
答案 0 :(得分:6)
"但是,我对这个问题感到有点困惑,使用数组而不是使用容器可以更有效/更容易地做什么?"
好吧,如果您指的是 c风格的数组,使用当前的c ++标准,那么经典的标准c ++容器类的缺点就没有了什么(比如例如std::vector
)恕我直言。它们具有可分配内存(具有new()
)的依赖性,这很可能是对当前(OS /裸机)环境的限制,因为没有开箱即用。
当前标准提供了std::array
,它在没有动态内存分配需求的情况下工作,但满足所有声明:
" 1。未检查下标"
std::array
执行下标检查
" 2。通常需要从堆中分配内存"
客户的选择是与std::array
实际分配的位置。 std::vector
无论如何都可以做到这一点。
" 3。不容易在中间插入元素"
嗯,开箱即用的std::array
不能很好地支持这一点。但是,std::vector
和其他容器类再次支持这一点(只要您的环境支持动态内存分配)
" 4。总是作为参考传递"
std::array
支持通过引用传递,并且使用c样式数组可以实现更好(无法实现)。
虽然可能存在例如特殊情况。可重用的对象实例池或flyweight对象实例,您可能希望使用placement new()
运算符来解决。这些解决方案的实现通常会让您在原始的C风格阵列上运行。
答案 1 :(得分:4)
内置数组是一个低级工具,界面有些尴尬。但是,它们需要更好地实现使用类:C ++的一个好处是暴露了许多低级工具来创建更高级抽象的有效实现。对我来说,内置数组的主要用途是:
std::vector<T>
或std::array<T, N>
(好吧,std::vector<...>
和家人并不真正使用内置数组,但直接处理原始内存内部)。std::array<...>
无法使用{推导出参数的数量和任何内容初始化的{1}}不会有固定的大小。)尽管std::initializer_list<T>
实际上只是重写了[内置数组]的某些功能,但它具有很好的功能,即调试实现可以断言所做的假设。
答案 2 :(得分:3)
堆栈上的数组可能比vector
更有效,因为vector
将始终执行单独的内存分配。你不太可能注意到这种差异,除非它是在一个大的紧密循环中多次执行的。
答案 3 :(得分:1)
或者实际上没有这样的东西,我真的不应该关心数组了吗?
考虑到C ++可以追溯到1983年,并且从那时起它已经发生了许多重大变化。现在可用的容器类是设计以避免您列出的陷阱,因此在这些方面它们更好并不奇怪。但是,对于C风格的数组,您可以使用现代容器类来完成一件事:您可以使用非常旧的编译器编译代码。如果你迫切需要保持与1980年代中期的编译器的兼容性,那么你应该坚持使用C风格的数组。否则,请使用更新,更好的方法。
答案 4 :(得分:1)
c-stlye数组比stl容器(特别是std::array
)有几个优点。当然,反过来也是如此。
首先,对于c风格的数组,您可以控制内存布局,这在解释网络数据包或任何类似的数据源时非常有用。这允许您将一块内存强制转换为结构,从而节省了复制/赋值操作,这在某些性能敏感的应用程序中是必需的。
另一个原因是简单性 - 如果您不需要std容器提供的任何好处,为什么要使用它们?
兼容性 - 不同的stl实现将随着不同的编译器而改变。在共享库(so / dll)的接口中使用数组而不是stl容器允许用户使用几乎任何编译器对共享库进行编写。对于stl容器,这显然不正确。
最后还有低级优化。在某些情况下,数组可能比它们的等效std::array
更快,尽管这些情况有点罕见。