Ответ 1
В С++ 11, где std::array
, ответ "да, следует избегать массивов". До С++ 11 вам может понадобиться использовать массивы C для распределения массивов в автоматическом хранилище (т.е. В стеке).
Так как существуют std::list
и std::vector
, существует ли причина использовать традиционные C-массивы в С++ или их следует избегать, как и malloc
?
В С++ 11, где std::array
, ответ "да, следует избегать массивов". До С++ 11 вам может понадобиться использовать массивы C для распределения массивов в автоматическом хранилище (т.е. В стеке).
Определенно, хотя с std::array
в С++ 11, практически только для
статические данные. С массивами стиля 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
), так как он
исключает весь порядок инициализации; данные предварительно загружены,
перед тем, как любой действительный код может быть выполнен.
Наконец, связанный с вышесказанным, компилятор может вычислить фактическое размер массива из инициализаторов. Вам не нужно их подсчитывать.
Если у вас есть доступ к С++ 11, std::array
решает первые две проблемы,
и определенно следует использовать в предпочтении массивам стиля C в
первый случай. Однако он не касается третьего, и
размер компилятора массив в соответствии с количеством инициализаторов равен
по-прежнему является веской причиной для предпочтения массивов стилей C.
Никогда не говорите "никогда", но я бы согласился с тем, что их роль значительно уменьшается из-за истинных структур данных из STL.
Я бы также сказал, что инкапсуляция внутри объектов должна минимизировать влияние таких вариантов. Если массив является частным членом данных, вы можете его менять или удалять, не затрагивая клиентов вашего класса.
Я работал над критическими критическими системами, где вы не можете использовать распределение динамической памяти. Память всегда должна находиться в стеке. Поэтому в этом случае вы будете использовать массивы, поскольку размер фиксируется во время компиляции.
array
в c++
дает вам фиксированную размерную быструю альтернативу динамического размера std::vector
и std::list
. std:: array является одним из добавлений в c++11
. Он обеспечивает преимущества std-контейнеров, сохраняя при этом обобщенную семантику типов массивов в стиле C.
Итак, в c++11
я бы обязательно использовал std::array
, где это необходимо, над вектором. Но я бы избегал массива стиля C в C++03
.
Как правило, нет, я не могу придумать причину использования необработанных массивов, скажем, vectors
. Если новый код.
Возможно, вам придется прибегать к использованию массивов, если ваши библиотеки должны быть совместимы с кодом, который ожидает массивы и необработанные указатели.
Я знаю, что многие люди указывают std:: array для выделения массивов в стеке и std::vector для кучи. Но, похоже, ни одна из них не поддерживает нестандартное выравнивание. Если вы делаете какой-либо цифровой код, в котором вы хотите использовать инструкции SSE или VPX (для этого требуется соответственно выравнивание по 128 или 256 байт), массивы C по-прежнему выглядят наилучшим образом.
Я бы сказал, что массивы по-прежнему полезны, если вы храните небольшое статическое количество данных, почему бы и нет.
Единственное преимущество массива (конечно, завернутое в то, что будет автоматически управлять его освобождением при необходимости) через std::vector
Я могу думать о том, что vector
не может передать право собственности на свои данные, если ваш компилятор не поддерживает C + +11 и переместить конструкторы.
C представляют собой фундаментальную структуру данных, поэтому будут случаи, когда ее лучше использовать. Однако для общего случая используйте более сложные структуры данных, которые округляют углы базовых данных. С++ позволяет вам делать очень интересные и полезные вещи с памятью, многие из которых работают с простыми массивами.
Вы должны использовать контейнеры STL внутри себя, но вы не должны передавать указатели на такие контейнеры между разными модулями, иначе вы окажетесь в адском зависимости. Пример:
std::string foo;
// fill foo with stuff
myExternalOutputProc(foo.c_str());
- очень хорошее решение, но не
std::string foo;
// fill foo with stuff
myExternalOutputProc(&foo);
Причина в том, что std::string может быть реализована по-разному, но строка c-style всегда является строкой c-стиля.