为什么我应该使用简单数组而不是容器类?

时间:2014-12-16 20:14:25

标签: c++ arrays containers

使用数组而不是容器可以更有效地完成什么(如果有的话)?

我最近了解了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

我想有很多情况,人们可以忍受这些缺点。但是,我对这个问题感到有些困惑,使用数组而不是容器可以更有效/更容易地完成什么?或者实际上没有这样的东西,我真的不应该关心数组了吗?

5 个答案:

答案 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 ++的一个好处是暴露了许多低级工具来创建更高级抽象的有效实现。对我来说,内置数组的主要用途是:

  1. 实现更高级别抽象的机制,例如std::vector<T>std::array<T, N>(好吧,std::vector<...>和家人并不真正使用内置数组,但直接处理原始内存内部)。
  2. 当我需要使用在堆栈上分配的值序列初始化的值数组时,我使用内置数组(std::array<...>无法使用{推导出参数的数量和任何内容初始化的{1}}不会有固定的大小。)
  3. 尽管std::initializer_list<T>实际上只是重写了[内置数组]的某些功能,但它具有很好的功能,即调试实现可以​​断言所做的假设。

    顺便说一句,你列出的并不包括更大的问题:如果你有一个可变大小的数组,你需要给你的元素类型一个默认的构造函数。使用C ++ 11,默认构造函数至少可以默认(如果您的类需要另一个构造函数,这是一个问题),这可以避免初始化即将初始化的对象。但是,各种容器类在图片中占用了很多复杂性。

答案 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更快,尽管这些情况有点罕见。