std::allocate_shared, std::allocate_shared_for_overwrite
Определено в заголовке <memory> | ||
|---|---|---|
template< class T, class Alloc, class... Args > shared_ptr<T> allocate_shared( const Alloc& alloc, Args&&... args ); | (1) | (с C++11) (T — не массив) |
template< class T, class Alloc > shared_ptr<T> allocate_shared( const Alloc& alloc, std::size_t N ); | (2) | (с C++20) (T — U[]) |
template< class T, class Alloc > shared_ptr<T> allocate_shared( const Alloc& alloc ); | (3) | (с C++20) (T — U[N]) |
template< class T, class Alloc >
shared_ptr<T> allocate_shared( const Alloc& alloc, std::size_t N,
const std::remove_extent_t<T>& u );
| (4) | (с C++20) (T — U[]) |
template< class T, class Alloc >
shared_ptr<T> allocate_shared( const Alloc& alloc,
const std::remove_extent_t<T>& u );
| (5) | (с C++20) (T — U[N]) |
template< class T, class Alloc > shared_ptr<T> allocate_shared_for_overwrite( const Alloc& alloc ); | (6) |
(с C++20) (T — не U[]) |
template< class T, class Alloc > shared_ptr<T> allocate_shared_for_overwrite( const Alloc& alloc, std::size_t N ); | (7) | (с C++20) (T — U[]) |
T и оборачивает его в std::shared_ptr, используя args в качестве списка параметров для конструктора T. Объект конструируется так же, как в выражении ::new (pv) T(v)(до C++20)std::allocator_traits<A2>::construct(a, pv, v)(с C++20), где pv — внутренний указатель void* на хранилище, подходящее для объекта типа T, а a — копия распределителя, перенастроенного на std::remove_cv_t<T>. Хранилище обычно больше, чем sizeof(T), чтобы использовать одно выделение памяти для блока управления shared указателем и объекта T. Конструктор std::shared_ptr, вызываемый этой функцией, позволяет shared_from_this с указателем на только что созданный объект типа T. Все выделения памяти выполняются с копией alloc, которая должна удовлетворять требованиям Allocator.std::allocator_traits<A2>::construct(a2, pv), где a2 типа A2 — копия распределителя, перенастроенная для управления объектами типа std::remove_cv_t<std::remove_all_extents_t<T>>. Перегрузка (2) создаёт массив размером N вдоль первого измерения. Элементы массива инициализируются в порядке возрастания их адресов, а когда их жизненный цикл заканчивается, они уничтожаются в обратном порядке их первоначального построения.u. Если std::remove_extent_t<T> сам по себе не является типом массива, это выполняется как если бы выражение распределителя совпадало с (1), за исключением того, что распределитель перенастраивается на std::remove_cv_t<std::remove_all_extents_t<T>>. В противном случае это выполняется как если бы каждый элемент (не являющийся массивом) (возможно, многомерного) массива был инициализирован соответствующим элементом из u с использованием того же выражения распределителя, что и в (1), за исключением того, что распределитель перенастраивается на тип std::remove_cv_t<std::remove_all_extents_t<T>>. Перегрузка (4) создаёт массив размером N вдоль первого измерения. Элементы массива инициализируются в порядке возрастания их адресов, а когда их жизненный цикл заканчивается, они уничтожаются в обратном порядке их первоначального построения.T не является массивом, и (3), если T — U[N], за исключением того, что создаваемый объект инициализируется по умолчанию.Для allocate_shared, объект (или отдельные элементы массива для (2-5))(с C++20) уничтожаются с помощью выражения std::allocator_traits<A2>::destroy(a, p), где p — указатель на объект, а a — копия распределителя, переданного в allocate_shared, перенастроенный на тип уничтожаемого объекта.
| Для | (с C++20) |
Параметры
| alloc | - | используемый распределитель |
| args... | - | список аргументов, с помощью которых будет создан экземпляр T |
| N | - | размер массива |
| u | - | начальное значение для инициализации каждого элемента массива |
Возвращаемое значение
Указатель на экземпляр типа T.
Исключения
Может бросить исключения, выброшенные Alloc::allocate() или конструктором T. Если исключение брошено, (1) не оказывает никакого эффекта. Если исключение брошено во время построения массива, уже проинициализированные элементы уничтожаются в обратном порядке.(с C++20)
Примечания
Подобно std::make_shared, эта функция обычно выполняет только одно выделение и помещает как объект T, так и блок управления в выделенный блок памяти (стандарт рекомендует, но не требует этого, все известные реализации это делают). Копия alloc хранится в составе блока управления, чтобы её можно было использовать для освобождения памяти, когда счётчики общих и слабых ссылок достигнут нуля.
В отличие от std::shared_ptr constructors, std::allocate_shared не принимает отдельный пользовательский деструктор: используемый распределитель используется для уничтожения блока управления и объекта T, а также для освобождения их общего блока памяти.
|
| (до C++20) |
Конструктор активирует shared_from_this с указателем ptr типа U* означает, что он определяет, имеет ли U явную и доступную(с C++17) базовую специализацию std::enable_shared_from_this, и если да, то конструктор оценивает утверждение:
if (ptr != nullptr && ptr->weak_this.expired())
ptr->weak_this = std::shared_ptr<std::remove_cv_t<U>>(
*this, const_cast<std::remove_cv_t<U>*>(ptr));Где weak_this — скрытый мутабельный член std::weak_ptr объекта std::enable_shared_from_this. Присвоение члена weak_this не является атомарным и конфликтует с любым потенциальным одновременным доступом к тому же объекту. Это гарантирует, что будущие вызовы shared_from_this() будут совмещать владение с std::shared_ptr созданным этим указателем.
Проверка ptr->weak_this.expired() в демонстрационном коде выше гарантирует, что weak_this не переприсваивается, если уже указывает владельца. Эта проверка необходима начиная с C++17.
| Макроинструкция проверки наличия функции | Значение | Std | Функция |
|---|---|---|---|
__cpp_lib_smart_ptr_for_overwrite | 202002L | (C++20) | Создание интеллектуальных указателей с инициализацией по умолчанию (std::allocate_shared_for_overwrite, std::make_shared_for_overwrite, std::make_unique_for_overwrite); перегрузки (6,7) |
Пример
См. также
создаёт новый shared_ptr (публичный член-функция) |
|
|
(C++20) | создаёт shared указатель, управляющий новым объектом (функция-шаблон) |
© cppreference.com
Licensed under the Creative Commons Attribution-ShareAlike Unported License v3.0.
https://en.cppreference.com/w/cpp/memory/shared_ptr/allocate_shared