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

时间:2012-05-23 10:27:06

标签: c++ arrays conventions

由于存在std::liststd::vector,是否有理由在C ++中使用传统的C数组,或者应该避免使用它们,就像malloc一样?

11 个答案:

答案 0 :(得分:109)

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

答案 1 :(得分:85)

当然,尽管在C ++ 11中使用std::array,但实际上仅适用于 静态数据。 C风格阵列有三个重要优势 std::vector

  • 他们不需要动态分配。出于这个原因,C风格 数组是你可能有很多非常喜欢的地方 小阵列。说出像n维点的东西:

    template <typename T, int dims>
    class Point
    {
        T myData[dims];
    // ...
    };
    

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

  • 支持静态初始化。这只是静态问题 数据,如:

    struct Data { int i; char const* s; };
    Data const ourData[] =
    {
        { 1, "one" },
        { 2, "two" },
        //  ...
    };
    

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

  • 最后,与上述相关,编译器可以计算出实际值 初始化器中数组的大小。你无需计算它们。

如果您有权访问C ++ 11,std::array解决了前两个问题, 并且绝对应该优先使用C风格的数组 第一个案例。然而,它并没有解决第三个问题 编译器根据初始化器的数量维度 仍然是更喜欢C风格数组的正当理由。

答案 2 :(得分:15)

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

我还会说对象内部的封装应该尽量减少这样的选择的影响。如果数组是私有数据成员,您可以在不影响类的客户端的情况下将其交换进去。

答案 3 :(得分:11)

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

答案 4 :(得分:6)

array中的

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

所以在c++11我肯定会在需要的地方使用std::array而不是矢量。但我会在C++03中避免使用C样式数组。

答案 5 :(得分:4)

通常情况下,没有,我想不出使用原始数组的原因,比如vectors如果代码是新的

如果您的库需要与需要数组和原始指针的代码兼容,则可能不得不求助于使用数组。

答案 6 :(得分:4)

我知道很多人指出std :: array用于在堆栈上分配数组,而std :: vector用于堆。但似乎都不支持非本地对齐。如果您正在使用任何类型的数字代码,您需要使用SSE或VPX指令(因此分别需要128或256字节对齐),C阵列似乎仍然是您最好的选择。

答案 7 :(得分:3)

我想说数组仍然有用,如果你存储一小部分静态数据,为什么不存在。

答案 8 :(得分:2)

数组的唯一优势(当然包含在需要时自动管理其释放的内容)std::vector我可以考虑的是vector无法传递其数据的所有权,除非你的编译器支持C ++ 11并移动构造函数。

答案 9 :(得分:2)

C样式数组是一种基本的数据结构,因此有时会更好地使用它。但是,对于一般情况,请使用更高级的数据结构来舍入基础数据的角。 C ++允许你用内存做一些非常有趣和有用的东西,其中许多都使用简单的数组。

答案 10 :(得分:1)

你应该在内部使用STL容器,但你不应该在不同的模块之间传递指向这些容器的指针,否则你将最终依赖地狱。例如:

std::string foo;
//  fill foo with stuff
myExternalOutputProc(foo.c_str());

是一个非常好的解决方案,但不是

std::string foo;
//  fill foo with stuff
myExternalOutputProc(&foo);

原因是std :: string可以用许多不同的方式实现,但c风格的字符串总是c风格的字符串。