由于存在std::list
和std::vector
,是否有理由在C ++中使用传统的C数组,或者应该避免使用它们,就像malloc
一样?
答案 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::vector
和std::list
的固定大小快速替代方案。 std::array是c++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风格的字符串。