Первоначально шаблоны функций Boostmake_sharedиallocation_sharedбыли предназначены только для эффективного распределения общих объектов. Необходимо обеспечить эффективное распределение общих массивов. Одна критика шаблона классаshared_arrayвсегда заключалась в отсутствии утилиты make_shared, которая обеспечивает только одно распределение.
Файлы заголовкаипредоставляют шаблоны функций, перегрузкиmake_sharedивыделяют_sharedдля типов массивов, чтобы удовлетворить эту потребность.make_sharedиспользует глобального оператораnewдля выделения памяти, тогда какallocate_sharedиспользует выделенный пользователем распределитель, позволяющий более точно контролировать.
namespace boost {
template<class U> // U is T[]
shared_ptr<U> make_shared(size_t size);
template<class U, class A> // U is T[]
shared_ptr<U> allocate_shared(const A& allocator, size_t size);
template<class U> // U is T[N]
shared_ptr<U> make_shared();
template<class U, class A> // U is T[N]
shared_ptr<U> allocate_shared(const A& allocator);
template<class U> // U is T[]
shared_ptr<U> make_shared(size_t size, const T& value);
template<class U, class A> // U is T[]
shared_ptr<U> allocate_shared(const A& allocator, size_t size, const T& value);
template<class U> // U is T[N]
shared_ptr<U> make_shared(const T& value);
template<class U, class A> // U is T[N]
shared_ptr<U> allocate_shared(const A& allocator, const T& value);
template<class U> // U is T[]
shared_ptr<U> make_shared_noinit(size_t size);
template<class U, class A> // U is T[]
shared_ptr<U> allocate_shared_noinit(const A& allocator, size_t size);
template<class U> // U is T[N]
shared_ptr<U> make_shared_noinit();
template<class U, class A> // U is T[N]
shared_ptr<U> allocate_shared_noinit(const A& allocator);
}
template<class U>
shared_ptr<U> make_shared(args);
template<class U, class A>
shared_ptr<U> allocate_shared(const A& allocator, args);
template<class U>
shared_ptr<U> make_shared_noinit(args);
template<class U, class A>
shared_ptr<U> allocate_shared_noinit(const A& allocator, args);
Требуется:Uимеет формуTилиT[N].Aдолжен бытьРаспределителем, как описано в разделе 17.6.3.5Требования к Распределителям] Стандарта C++. Конструктор и разрушитель копийАне должны делать исключений.
Эффекты:Выделяет память для объекта типаU(илиT [размер], когдаUявляетсяT, гдеразмеропределяется изargs, как указано конкретной перегрузкой. Объект инициализируется в соответствии с конкретной перегрузкой. Шаблонывыделяют_sharedивыделяют_shared_noinitиспользуют копиюраспределителядля выделения памяти. Если бросается исключение, функции не имеют эффекта.
Возвращает:Ashared_ptrэкземпляр, который хранит и владеет адресом вновь построенного объекта.
Броски:bad_alloc, исключение, брошенное изA::allocate, или из инициализации объекта.
Замечания:
Эта реализация выполняет не более одного выделения памяти. Это обеспечивает эффективность, эквивалентную навязчивому интеллектуальному указателю.
Если объект типа массиваTуказан для инициализации до значения одного и того же типазначения, это должно толковаться как означающее, что каждый элемент массива объекта инициализирован до соответствующего элемента отзначения.
Если объект типа массива указан как инициализируемый по значению, это должно толковаться как означающее, что каждый элемент массива объекта инициализирован по значению.
Элементы массива инициализируются в порядке возрастания их адресов.
Если субобъект немассивного типаTуказан для инициализации в значениезначение,make_sharedдолжен выполнить эту инициализацию посредством выражения::new(ptr) T(value), гдеptrимеет типпустоту*и указывает на хранилище, пригодное для хранения объекта типаT.
Когда субобъект немассивного типаTуказывается для инициализации к значениюзначение,выделение_разделенноедолжно выполнять эту инициализацию посредством выраженияallocator_traits::construct(a2, ptr, значение), гдеptrуказывает на хранение, подходящее для удержания объекта типаTиa2типа A2 является отскоком копии распределителяраспределителя, переданнойвыделению_sharedтаким образом, что егозначение_типявляетсяT.
Когда субобъект немассивного типаTопределен как инициализированный по значению,make_sharedдолжен выполнить эту инициализацию посредством выражения::new(ptr) T(), гдеptrимеет видvoid*и указывает на хранилище, пригодное для удержания объекта типаT.
Когда субобъект немассивного типаTопределен как инициализированный по значению,allocate_sharedдолжен выполнить эту инициализацию посредством выраженияallocator_traits::construct(a2, ptr), гдеptrуказывает на хранилище, пригодное для хранения объекта типаTиa2типа A2 является отскоком копии распределителяallocator, переданнойallocate_sharedтаким образом, что егоvalue_typeявляетсяT.
Когда субобъект немассивного типаTопределен как инициализированный по умолчанию,make_shared_noinitиallocate_shared_noinitдолжен выполнить эту инициализацию посредством выражения::new(ptr) T, гдеptrимеет видvoid*и указывает на хранилище, пригодное для удержания объекта типаT.
Когда срок службы объекта, управляемого обратным значением, заканчивается или когда инициализация элемента массива бросает исключение, инициализированные элементы должны быть уничтожены в обратном порядке их построения.
Примечания:Эти функции обычно выделяют больше памяти, чемразмер (U), чтобы обеспечить внутренние структуры бухгалтерского учета, такие как количество ссылок.
template<class U>
shared_ptr<U> make_shared_noinit(size_t size);
template<class U, class A>
shared_ptr<U> allocate_shared_noinit(const A& allocator, size_t size);
Февраль 2014. Глен Фернандес обновил перегрузки make_shared и allocation_shared, чтобы соответствовать спецификации в стандартной бумаге C++N3870, включая разрешение отчета о дефекте стандартной библиотеки C++ 2070 и сокращение пространственных накладных расходов внутренних структур бухгалтерского учета.
Ноябрь 2012. Глен Фернандес внес вклад в реализацию make_shared и allocation_shared для массивов.
Статья make_shared and allocate_shared for arrays раздела может быть полезна для разработчиков на c++ и boost.
Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.