Так как существуют std::list
и std::vector
, существует ли причина использовать традиционные C-массивы в С++ или их следует избегать, как и malloc
?
Должны ли массивы использоваться на С++?
Ответ 1
В С++ 11, где std::array
, ответ "да, следует избегать массивов". До С++ 11 вам может понадобиться использовать массивы C для распределения массивов в автоматическом хранилище (т.е. В стеке).
Ответ 2
Определенно, хотя с 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.
Ответ 3
Никогда не говорите "никогда", но я бы согласился с тем, что их роль значительно уменьшается из-за истинных структур данных из STL.
Я бы также сказал, что инкапсуляция внутри объектов должна минимизировать влияние таких вариантов. Если массив является частным членом данных, вы можете его менять или удалять, не затрагивая клиентов вашего класса.
Ответ 4
Я работал над критическими критическими системами, где вы не можете использовать распределение динамической памяти. Память всегда должна находиться в стеке. Поэтому в этом случае вы будете использовать массивы, поскольку размер фиксируется во время компиляции.
Ответ 5
array
в c++
дает вам фиксированную размерную быструю альтернативу динамического размера std::vector
и std::list
. std:: array является одним из добавлений в c++11
. Он обеспечивает преимущества std-контейнеров, сохраняя при этом обобщенную семантику типов массивов в стиле C.
Итак, в c++11
я бы обязательно использовал std::array
, где это необходимо, над вектором. Но я бы избегал массива стиля C в C++03
.
Ответ 6
Как правило, нет, я не могу придумать причину использования необработанных массивов, скажем, vectors
. Если новый код.
Возможно, вам придется прибегать к использованию массивов, если ваши библиотеки должны быть совместимы с кодом, который ожидает массивы и необработанные указатели.
Ответ 7
Я знаю, что многие люди указывают std:: array для выделения массивов в стеке и std::vector для кучи. Но, похоже, ни одна из них не поддерживает нестандартное выравнивание. Если вы делаете какой-либо цифровой код, в котором вы хотите использовать инструкции SSE или VPX (для этого требуется соответственно выравнивание по 128 или 256 байт), массивы C по-прежнему выглядят наилучшим образом.
Ответ 8
Я бы сказал, что массивы по-прежнему полезны, если вы храните небольшое статическое количество данных, почему бы и нет.
Ответ 9
Единственное преимущество массива (конечно, завернутое в то, что будет автоматически управлять его освобождением при необходимости) через std::vector
Я могу думать о том, что vector
не может передать право собственности на свои данные, если ваш компилятор не поддерживает C + +11 и переместить конструкторы.
Ответ 10
Макеты типовC представляют собой фундаментальную структуру данных, поэтому будут случаи, когда ее лучше использовать. Однако для общего случая используйте более сложные структуры данных, которые округляют углы базовых данных. С++ позволяет вам делать очень интересные и полезные вещи с памятью, многие из которых работают с простыми массивами.
Ответ 11
Вы должны использовать контейнеры 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-стиля.