Контейнеры против смарт-указателей в C ++ - PullRequest
0 голосов
/ 15 февраля 2019

Как я могу решить, выбирая между std :: container (std::vector или std::array) и умными указателями, указывающими на массивы

Я знаю, что контейнеры - это объекты для управления памятью.Они безопасны для исключительных ситуаций и не будут иметь утечки памяти, а также обеспечивают множество функций для управления памятью (push.back и т. Д.), А интеллектуальные указатели являются указателями, которые также не пропускают память, поскольку они удаляют себя, когда они больше не нужны (как unique_ptr при выходе из области видимости).Вероятно, в контейнерах накладываются накладные расходы каждый раз, когда они создаются.

Мой вопрос: как я могу решить, какой метод использовать и почему.

std::vector <unsigned char>myArray(3 * outputImageHight * outputImageWidth);

std::unique_ptr<unsigned char[]>myArray(new unsigned char[3 * outputImageHight * outputImageWidth]);

Ответы [ 3 ]

0 голосов
/ 15 февраля 2019

Всегда используйте контейнеры STL, кроме случаев, когда у вас есть веские основания использовать указатели.Причины - надежность и читабельность, ИМО.

0 голосов
/ 15 февраля 2019

std::vector, главным образом потому, что он лучше представляет «последовательность элементов в смежной памяти», это представление по умолчанию для этого и позволяет использовать широкий спектр общих операций.

vector имеет перемещениесемантика, поэтому преимущество std :: unique_ptr ограничено.

Если вам повезет, ваша реализация STL `обеспечивает небольшую векторную оптимизацию, пропуская выделение памяти для небольших размеров.
- edit: I wasn 'Не знаю, SBO, по-видимому, запрещено стандартом - извините за ваши надежды, спасибо @ KarlNicholl

Если требуется семантика указателя, unique_ptr<vector<T>> или shared_ptr<vector<T>> является допустимым выборомс небольшими накладными расходами.

boost действительно представил shared_array и т. д., которые лучше отражают ваш второй вариант, но я не видел, чтобы они получили большую тягу.

0 голосов
/ 15 февраля 2019

Я бы использовал вектор.Ваша версия указателя не предлагает никаких улучшений по сравнению с вектором, и вы теряете много полезных функций.Скорее всего, вам понадобится измерить размер и выполнить итерацию вашего массива в какой-то момент, с вектором, который вы получите бесплатно, тогда как вам нужно будет реализовать его самостоятельно для вашей версии указателя;в этот момент вы, возможно, также просто использовали вектор для начала.

Там может быть затратами на производительность, создавая вектор, но я сомневаюсь, что для большинства приложений это будет узким местом.,Если вы создаете так много векторов, что создание их экземпляров стоит вашего времени, вы, вероятно, будете более умны в управлении ими (объединение памяти, пользовательских распределителей векторов и т. Д.).Если сомневаетесь, измерьте.

Один из примеров, где вам может понадобиться использовать версию unique_ptr<>, может быть, если вы работаете с библиотекой, написанной на C, где вы теряете право собственности на массив.Например:

std::unique_ptr<unsigned char[]>myArray(
    new unsigned char[3 * outputImageHight * outputImageWidth]);

my_c_lib_data_t cLibData;
int result = my_c_lib_set_image(cLibData, myArray);

if (MYLIB_SUCCESS == result)
    // mylib successfully took ownership of the char array, so release the pointer.
    myArray.release();

Если у вас есть выбор, предпочитайте использовать контейнеры в стиле C ++, где это возможно.

...