Namespaces
Variants

std:: allocate_shared, std:: allocate_shared_for_overwrite

From cppreference.net
Memory management library
( exposition only* )
Allocators
Uninitialized memory algorithms
Constrained uninitialized memory algorithms
Memory resources
Uninitialized storage (until C++20)
( until C++20* )
( until C++20* )
( until C++20* )

Garbage collector support (until C++23)
(C++11) (until C++23)
(C++11) (until C++23)
(C++11) (until C++23)
(C++11) (until C++23)
(C++11) (until C++23)
(C++11) (until C++23)
Определено в заголовочном файле <memory>
template < class T, class Alloc, class ... Args >
shared_ptr < T > allocate_shared ( const Alloc & alloc, Args && ... args ) ;
(1) (начиная с C++11)
template < class T, class Alloc >
shared_ptr < T > allocate_shared ( const Alloc & alloc, std:: size_t N ) ;
(2) (начиная с C++20)
template < class T, class Alloc >
shared_ptr < T > allocate_shared ( const Alloc & alloc ) ;
(3) (начиная с C++20)
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)
template < class T, class Alloc >

shared_ptr < T > allocate_shared ( const Alloc & alloc,

const std:: remove_extent_t < T > & u ) ;
(5) (начиная с C++20)
template < class T, class Alloc >
shared_ptr < T > allocate_shared_for_overwrite ( const Alloc & alloc ) ;
(6) (начиная с C++20)
template < class T, class Alloc >

shared_ptr < T > allocate_shared_for_overwrite ( const Alloc & alloc,

std:: size_t N ) ;
(7) (начиная с C++20)

Выделяет память для объекта, используя копию alloc (пересвязанную для неопределённого value_type ), и инициализирует объект предоставленными аргументами. Возвращает объект std::shared_ptr , управляющий вновь созданным объектом.

1) Объект имеет тип T и конструируется как если бы с помощью std:: allocator_traits < Alloc > :: construct
( a, pt, ( std:: forward < Args > ( args ) ... )
, где pt является указателем std:: remove_cv_t < T < * на область памяти, подходящую для хранения объекта типа std:: remove_cv_t < T > . Если объект должен быть уничтожен, он уничтожается как если бы с помощью std:: allocator_traits < Alloc > :: destroy ( a, pt ) , где pt является указателем на этот объект типа std:: remove_cv_t < T > .
В приведенном выше описании, a имеет тип Alloc и является потенциально пересвязанной копией alloc .

Эта перегрузка участвует в разрешении перегрузки только если T не является типом массива.

(since C++20)
2) Объект имеет тип std:: remove_extent_t < T > [ N ] . Каждый элемент имеет значение по умолчанию.
Эта перегрузка участвует в разрешении перегрузки только если T является типом неограниченного массива.
3) Объект имеет тип T . Каждый элемент имеет значение по умолчанию.
Эта перегрузка участвует в разрешении перегрузки только если T является типом ограниченного массива.
4) Объект имеет тип std:: remove_extent_t < T > [ N ] . Каждый элемент имеет начальное значение u .
Эта перегрузка участвует в разрешении перегрузки только если T является типом неограниченного массива.
5) Объект имеет тип T . Каждый элемент имеет начальное значение u .
Эта перегрузка участвует в разрешении перегрузки только если T является типом ограниченного массива.
6) Объект имеет тип T .
  • Если T не является типом массива, объект конструируется как если бы с помощью :: new ( pv ) T , где pv — это указатель типа void * на область памяти, подходящую для хранения объекта типа T . Если объект должен быть уничтожен, он уничтожается как если бы с помощью pt - > ~T ( ) , где pt — это указатель на данный объект типа T .
  • Если T является типом ограниченного массива, начальное значение каждого элемента не определено.
Эта перегрузка участвует в разрешении перегрузки только если T не является типом массива или является типом ограниченного массива.
7) Объект имеет тип std:: remove_extent_t < T > [ N ] . Начальное значение не определено для каждого элемента.
Эта перегрузка участвует в разрешении перегрузки только если T является типом неограниченного массива.

Содержание

Инициализация и уничтожение элементов массива

В приведённом ниже описании, a имеет тип Alloc и является потенциально пересвязанной копией alloc .

Элементы массива типа U инициализируются в порядке возрастания их адресов.

  • Если U не является типом массива, каждый элемент конструируется как если бы следующим выражением, где pu является std:: remove_cv_t < U > * указателем на память, подходящую для хранения объекта типа std:: remove_cv_t < U > , и pv является void * указателем на память, подходящую для хранения объекта типа U :
2,3) std:: allocator_traits < Alloc > :: construct ( a, pu )
4,5) std:: allocator_traits < Alloc > :: construct ( a, pu, u )
6,7) :: new ( pv ) U
  • Иначе, рекурсивно инициализирует элементы каждого элемента. Для следующего измерения:
  • U становится std:: remove_extent_t < U > .
  • Для перегрузок (4,5) , u становится соответствующим элементом u .

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

Для каждого элемента массива не-массивного типа U , который должен быть уничтожен, он уничтожается как если бы следующим выражением:

2-5) std:: allocator_traits < Alloc > :: destroy ( a, pu ) , где pu является U * указателем на этот элемент массива типа U
6,7) pu - > ~U ( ) , где pu является указателем на этот элемент массива типа U
(начиная с C++20)

Параметры

alloc - используемый Allocator
args... - список аргументов для конструирования экземпляра T
N - используемый размер массива
u - начальное значение для инициализации каждого элемента массива

Возвращаемое значение

std::shared_ptr к объекту типа T или std:: remove_extent_t < T > [ N ] если T является типом неограниченного массива (начиная с C++20) .

Для возвращённого std::shared_ptr r , r. get ( ) возвращает ненулевой указатель, а r. use_count ( ) возвращает 1 .

Исключения

Может выбрасывать исключения, выброшенные из Alloc :: allocate ( ) или из конструктора T . Если исключение выброшено, (1) не имеет эффекта. Если исключение выброшено во время конструирования массива, уже проинициализированные элементы уничтожаются в обратном порядке (since C++20) .

Примечания

Эти функции обычно выделяют больше памяти, чем sizeof ( T ) чтобы обеспечить место для внутренних структур служебной информации, таких как счетчики ссылок.

Подобно std::make_shared , эта функция обычно выполняет только одно выделение памяти и размещает как объект T , так и блок управления в выделенном блоке памяти (стандарт рекомендует, но не требует этого, все известные реализации делают именно так). Копия alloc сохраняется как часть блока управления, чтобы её можно было использовать для освобождения памяти после того, как счётчики сильных и слабых ссылок достигнут нуля.

В отличие от std::shared_ptr constructors , std::allocate_shared не принимает отдельный пользовательский deleter: предоставленный аллокатор используется для разрушения блока управления и объекта T , а также для освобождения их общего блока памяти.

std::shared_ptr поддерживает массивы (начиная с C++17), но std::allocate_shared не поддерживает. Эта функциональность предоставляется boost::allocate_shared .

(до 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 не является атомарной операцией и конфликтует с любыми потенциально параллельными обращениями к тому же объекту. Это гарантирует, что последующие вызовы shared_from_this() будут разделять владение с std::shared_ptr , созданным данным конструктором из сырого указателя.

Тест ptr - > weak_this  . expired ( ) в приведённом коде гарантирует, что weak_this не будет переназначен, если он уже указывает на владельца. Этот тест обязателен начиная с C++17.

Макрос тестирования возможностей Значение Стандарт Функция
__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 )

Пример

#include <cstddef>
#include <iostream>
#include <memory>
#include <memory_resource>
#include <vector>
class Value
{
    int i;
public:
    Value(int i) : i(i) { std::cout << "Value(), i = " << i << '\n'; }
    ~Value() { std::cout << "~Value(), i = " << i << '\n'; }
    void print() const { std::cout << "i = " << i << '\n'; }
};
int main()
{
    // Создание полиморфного аллокатора с использованием монотонного буферного ресурса
    std::byte buffer[sizeof(Value) * 8];
    std::pmr::monotonic_buffer_resource resource(buffer, sizeof(buffer));
    std::pmr::polymorphic_allocator<Value> allocator(&resource);
    std::vector<std::shared_ptr<Value>> v;
    for (int i{}; i != 4; ++i)
        // Использование std::allocate_shared с пользовательским аллокатором
        v.emplace_back(std::allocate_shared<Value>(allocator, i));
    for (const auto& sp : v)
        sp->print();
} //< Все умные указатели автоматически очистятся при выходе из области видимости.

Вывод:

Value(), i = 0
Value(), i = 1
Value(), i = 2
Value(), i = 3
i = 0
i = 1
i = 2
i = 3
~Value(), i = 0
~Value(), i = 1
~Value(), i = 2
~Value(), i = 3

Отчеты о дефектах

Следующие отчеты об изменениях поведения, влияющие на дефекты, были применены ретроактивно к ранее опубликованным стандартам C++.

DR Applied to Behavior as published Correct behavior
LWG 3216 C++20 std::allocate_shared всегда перепривязывал
аллокатор перед созданием и уничтожением объектов
перепривязка опциональна
LWG 4024 C++20 было неясно, как уничтожаются объекты, созданные в
std::allocate_shared_for_overwrite
прояснено

Смотрите также

создает новый shared_ptr
(public member function)
создает shared pointer, который управляет новым объектом
(function template)