数组应该在C++中使用吗?

And*_*eas 95 c++ arrays conventions

由于std::liststd::vector存在,是有什么原因在C++中使用传统的C数组,还是应该尽量避免,只是喜欢malloc

das*_*ght 109

std::array可用的C++ 11中,答案是"是的,应该避免使用数组".在C++ 11之前,您可能需要使用C数组在自动存储(即堆栈)中分配数组.

  • @Nils数组也保证对齐.此外,自动存储分配("堆栈")比动态存储分配更快.如果我*知道*我有*正好*3个元素[例如,三角形的坐标],则没有理由使用向量. (16认同)
  • @zvrba - 使用std :: array vs C数组时检查生成的程序集.没有任何区别. (9认同)
  • std :: array是一个模板,它在构建时间和可能的代码大小方面影响大型项目,因为对于T,N的每个组合,模板被重新实例化. (4认同)
  • 但是,许多编译器仍然缺乏C++ 11支持.在缺少std :: array的情况下,你必须决定何时使用一个而不是另一个 (3认同)

Jam*_*nze 85

当然,尽管std::array在C++ 11中,实际上只用于静态数据.C样式数组有三个重要优势 std::vector:

  • 它们不需要动态分配.因此,在您可能拥有大量非常小的数组的情况下,首选C样式数组.说出类似n维点的东西:

    template <typename T, int dims>
    class Point
    {
        T myData[dims];
    // ...
    };
    
    Run Code Online (Sandbox Code Playgroud)

    通常,人们可能会想到一个dims非常小(2或3), T一个内置类型(double),并且最终可能会有 std::vector<Point>数百万个元素.你绝对不希望数百万的动态分配3倍.

  • 支持静态初始化.这只是静态数据的问题,其中包括:

    struct Data { int i; char const* s; };
    Data const ourData[] =
    {
        { 1, "one" },
        { 2, "two" },
        //  ...
    };
    
    Run Code Online (Sandbox Code Playgroud)

    这通常比使用向量(和std::string)更好,因为它避免了所有初始化问题的顺序; 在执行任何实际代码之前,数据已预先加载.

  • 最后,与上述相关,编译器可以从初始化器计算数组的实际大小.你不需要数数.

如果您可以访问C++ 11,那么std::array解决前两个问题,并且在第一种情况下绝对应该优先使用C样式数组.然而,它没有解决第三个问题,并且根据初始化器的数量使数组具有编译器维度仍然是优选C样式数组的正当理由.

  • C风格的数组初始化也消除了重复自己的需要.`int i [] = {1,2,3};`继续使用`int i [] = {1,2,3,4};`.`array <int,3>`需要手动更改为`array <int,4>`. (11认同)
  • @JoeWreschnig你可以轻易忘记的变化.如果你添加一个元素,编译器应该抱怨,但如果你删除一个元素,你最终会得到一个额外的0初始化元素.我仍然广泛使用C样式数组来处理这种静态数据. (10认同)
  • 通过使用[`make_array`函数](https://gist.github.com/2775736),类似于`make_pair`等,可以相当优雅地解决第三点.帽子提示为[@R.Martinho Fernandes](http://chat.stackoverflow.com/transcript/message/3820452#3820452). (4认同)
  • 第一句没有意义. (3认同)

duf*_*ymo 15

永远不要说"从不",但我同意他们的角色会因STL的真实数据结构而大大减少.

我还说在对象内部封装可以最大限度地减少这种选择的影响.如果数组是私有数据成员,则可以在不影响类的客户端的情况下交换它.


Ed *_*eal 11

我曾致力于安全关键系统,您无法使用动态内存分配.内存必须始终在堆栈中.因此,在这种情况下,您将使用数组,因为大小在编译时是固定的.

  • 在C++ 11之前我会同意,但是`std :: array <T>`在堆栈上分配,并且在原始数组上基本没有开销. (8认同)
  • 但在安全关键系统中,您不使用新的编译器功能(测试较少),并且您不使用boost. (6认同)
  • @ 111111 - 同意.但我知道该行业的一些人尚未转向C++ 11 (5认同)
  • 许多安全关键系统都是建立在OLD编译器上的,这些编译器甚至没有更新的编译器功能,因为更改工具链是一个缓慢,昂贵的过程,需要大量的文书工作,测试和认证. (3认同)

Vik*_*kas 6

arrayin c++为您提供固定大小的快速替代动态大小std::vectorstd::list.std :: array是其中一个补充c++11.它提供了std容器的好处,同时仍然提供了C样式数组的聚合类型语义.

因此,c++11我肯定会std::array在需要的地方使用矢量.但是我会避免使用C风格的数组C++03.