Просто небольшой вопрос по поводу shared_ptr
.
Это хорошая практика, чтобы использовать shared_ptr
указание на массив? Например,
shared_ptr<int> sp(new int[10]);
Если нет, то почему? Одна причина, о которой я уже знаю, это то, что нельзя увеличивать / уменьшать shared_ptr
. Следовательно, его нельзя использовать как обычный указатель на массив.
c++
c++11
shared-ptr
tshah06
источник
источник
std::vector
. Вы должны быть осторожны, чтобы передать массив, используя ссылки, чтобы вы не делали его копии. Синтаксис для доступа к данным чище, чем shared_ptr, и изменить его размер очень легко. И вы получите все добро STL, если захотите.std::array
. Он почти такой же, как необработанный массив, но с правильной семантикой для использования в большинстве библиотечных компонентов. Особенно объекты такого типа уничтожаютсяdelete
, а неdelete[]
. И, в отличие от этогоvector
, он хранит данные непосредственно в объекте, поэтому вы не получаете дополнительного распределения.Ответы:
С C ++ 17 ,
shared_ptr
может использоваться для управления динамически размещенным массивом.shared_ptr
Аргумент шаблона в этом случае должен бытьT[N]
илиT[]
. Так что вы можете написатьОт n4659 [util.smartptr.shared.const]
Чтобы поддержать это, тип члена
element_type
теперь определен какДоступ к элементам массива можно получить с помощью
operator[]
До C ++ 17 ,
shared_ptr
может не использоваться для управления динамически распределяемых массивов. По умолчаниюshared_ptr
вызоветdelete
управляемый объект, когда на него больше не будет ссылок. Однако, когда вы распределяете использование,new[]
вам нужно звонитьdelete[]
, а неdelete
освобождать ресурс.Для правильного использования
shared_ptr
с массивом вы должны предоставить пользовательское средство удаления.Создайте shared_ptr следующим образом:
Теперь
shared_ptr
будет правильно звонитьdelete[]
при уничтожении управляемого объекта.Пользовательский удалитель выше может быть заменен
std::default_delete
частичная специализация для типов массивовлямбда-выражение
Кроме того, если вам на самом деле не нужен общий доступ к управляемому объекту,
unique_ptr
лучше подходит для этой задачи, поскольку он имеет частичную специализацию для типов массивов.Изменения, внесенные расширениями C ++ для основ библиотеки
Еще одна альтернатива до C ++ 17, перечисленная выше, была предоставлена Технической спецификацией Основы библиотеки , которая дополнила
shared_ptr
его, чтобы он мог работать «из коробки» для случаев, когда он владеет массивом объектов. Текущий проектshared_ptr
изменений, намеченных для этого TS, может быть найден в N4082 . Эти изменения будут доступны черезstd::experimental
пространство имен и включены в<experimental/memory>
заголовок. Вот некоторые из важных изменений в поддержкеshared_ptr
массивов:- Определение
element_type
изменения типа члена- Член
operator[]
добавляется- В отличие от
unique_ptr
частичной специализации для массивов, обаshared_ptr<T[]>
иshared_ptr<T[N]>
будут действительными, и оба приведут кdelete[]
вызову в управляемом массиве объектов.источник
shared-array
.shared_ptr::get
возвращает указатель на управляемый объект. Таким образом, вы можете использовать его какsp.get()[0] = 1; ... sp.get()[9] = 10;
std::shared_ptr<int> sp( new int[10], std::default_delete<int[]>() );
см. Также en.cppreference.com/w/cpp/memory/default_deletestd::shared_ptr<std::array<int,N>>
должно быть достаточно.unique_ptr
получается эта частичная специализация, ноshared_ptr
нет?Возможно, более простая альтернатива, которую вы могли бы использовать
shared_ptr<vector<int>>
.источник
shared_ptr<array<int, 6>>
.