Должны ли массивы использоваться на С++?

Так как существуют 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-стиля.