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 起) |
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, |
(4) | (自 C++20 起) |
template< class T, class Alloc > shared_ptr<T> allocate_shared( const Alloc& alloc, |
(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, |
(7) | (自 C++20 起) |
使用 alloc 的副本(为未指明的 value_type
重新绑定)为对象分配内存,并使用提供的参数初始化对象。返回一个 std::shared_ptr 对象,管理新创建的对象。
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> 类型对象的指针。
Alloc
,它是 alloc 的潜在重新绑定副本。
此重载仅在 |
(自 C++20 起) |
T
是无界数组类型时参与重载决议。T
。每个元素都具有默认初始值。T
是有界数组类型时参与重载决议。T
是无界数组类型时参与重载决议。T
。每个元素都具有初始值 u。T
是有界数组类型时参与重载决议。T
。- 如果
T
不是数组类型,则对象的构造方式如同 ::new (pv) T,其中 pv 是一个 void* 指针,指向适合容纳T
类型对象的存储。如果要销毁对象,则销毁方式如同 pt->~T(),其中 pt 是指向T
类型对象的指针。 - 如果
T
是有界数组类型,则每个元素的初始值未指定。
T
不是数组类型或是有界数组类型时参与重载决议。T
是无界数组类型时参与重载决议。
初始化和销毁数组元素在以下描述中,a 的类型为 类型为
2,3) std::allocator_traits<Alloc>::construct(a, pu)
4,5) std::allocator_traits<Alloc>::construct(a, pu, u)
6,7) ::new (pv) U
当返回的 std::shared_ptr 管理的对象的生命周期结束时,或者当数组元素的初始化抛出异常时,已初始化的元素将按其原始构造的相反顺序销毁。 对于要销毁的非数组类型 6,7) pu->~U(),其中 pu 是指向类型为
U 的数组元素的指针 |
(自 C++20 起) |
[编辑] 参数
alloc | - | 要使用的 Allocator |
args... | - | 将用于构造 T 实例的参数列表 |
N | - | 要使用的数组大小 |
u | - | 用于初始化数组每个元素的初始值 |
[编辑] 返回值
指向 T
类型对象的 std::shared_ptr 或 std::remove_extent_t<T>[N],如果 T
是无界数组类型(自 C++20 起)。
对于返回的 std::shared_ptr r,r.get() 返回非空指针,且 r.use_count() 返回 1。
[编辑] 异常
可能抛出从 Alloc::allocate() 或 T
的构造函数抛出的异常。如果抛出异常,(1) 无效。如果在数组构造期间抛出异常,则已初始化的元素将按相反顺序销毁(自 C++20 起)。
[编辑] 注解
这些函数通常会分配比 sizeof(T) 更多的内存,以允许内部簿记结构(例如引用计数)。
与 std::make_shared 类似,此函数通常仅执行一次分配,并将 T
对象和控制块都放置在分配的内存块中(标准建议但不要求这样做,所有已知的实现都这样做)。alloc 的副本存储为控制块的一部分,以便在共享引用计数和弱引用计数都达到零时可以使用它来解除分配。
与 std::shared_ptr
构造函数
不同,std::allocate_shared
不接受单独的自定义删除器:提供的分配器用于销毁控制块和 T
对象,以及解除分配它们的共享内存块。
std::shared_ptr 支持数组类型(自 C++17 起),但 |
(直到 C++20) |
构造函数使用类型为 U*
的指针 ptr 启用 shared_from_this
意味着它确定 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 开始,此测试是必需的。
特性测试 宏 | 值 | 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) |
[编辑] 示例
#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() { // Create a polymorphic allocator using the monotonic buffer resource 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) // Use std::allocate_shared with the custom allocator v.emplace_back(std::allocate_shared<Value>(allocator, i)); for (const auto& sp : v) sp->print(); } //< All shared pointers will automatically clean up when they go out of scope.
输出
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 | 应用于 | 已发布行为 | 正确行为 |
---|---|---|---|
LWG 3216 | C++20 | std::allocate_shared 始终重新绑定分配器,然后在构造和销毁对象之前 |
重新绑定是可选的 |
LWG 4024 | C++20 | 不清楚在std::allocate_shared_for_overwrite 中构造的对象是如何销毁的 |
已明确 |
[编辑] 参见
构造新的 shared_ptr (公共成员函数) | |
创建管理新对象的共享指针 (函数模板) |