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, |
(4) | (自 C++20 起) (T 是 U[]) |
template< class T, class Alloc > shared_ptr<T> allocate_shared( const Alloc& alloc, |
(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
构造函数的参数列表,构造一个类型为 T
的对象,并使用 std::shared_ptr 将其包装起来。 对象的构造方式与表达式 ::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)
大,以便为共享指针的控制块和 T
对象使用一次分配。 此函数调用的 std::shared_ptr 构造函数使用指向新构造的类型为 T
的对象的指针启用 shared_from_this
。 所有内存分配都是使用 alloc 的副本完成的,该副本必须满足 Allocator 要求。 只有当 T 不是数组类型时,此重载才参与重载解析。A2
的 a2
是绑定到管理类型为 std::remove_cv_t<std::remove_all_extents_t<T>> 的对象的分配器的副本。 重载 (2) 创建一个沿其第一维大小为 N 的数组。 数组元素按其地址的升序进行初始化,当其生命周期结束时,按其原始构造的相反顺序进行销毁。对于 allocate_shared
,对象 (或 (2-5) 的各个数组元素)(自 C++20 起) 通过表达式 std::allocator_traits<A2>::destroy(a, p) 销毁,其中 p
是指向对象的指针,而 a
是传递给 allocate_shared
的分配器的副本,绑定到要销毁的对象的类型。
对于 |
(自 C++20 起) |
内容 |
[edit] 参数
alloc | - | 要使用的 Allocator |
args... | - | 用于构造 T 实例的参数列表 |
N | - | 要使用的数组大小 |
u | - | 用于初始化数组每个元素的初始值 |
[edit] 返回值
类型为 T
的实例的 std::shared_ptr。
[edit] 异常
可能会抛出从 Alloc::allocate() 或从 T
的构造函数抛出的异常。 如果抛出异常,(1) 将不起作用。 如果在数组的构造期间抛出异常,则已初始化的元素将按相反顺序销毁(自 C++20 起).
[edit] 注意
与 std::make_shared 一样,此函数通常只执行一次分配,并将 T
对象和控制块放在分配的内存块中(标准建议但不要求这样做,所有已知实现都这样做)。 alloc 的副本存储为控制块的一部分,以便在共享和弱引用计数都达到零时可以使用它来释放它。
与 std::shared_ptr
的 构造函数
不同,std::allocate_shared
不接受单独的自定义删除器:提供的分配器用于销毁控制块和 T
对象,以及用于释放其共享内存块。
std::shared_ptr 支持数组类型(自 C++17 起),但 |
(直到 C++20) |
构造函数使用类型为 U*
的指针 启用 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
是 std::enable_shared_from_this 的隐藏可变 std::weak_ptr 成员。 对 weak_this
成员的赋值不是原子性的,并且与对同一对象的任何潜在并发访问冲突。 这确保将来对 shared_from_this() 的调用将与由此原始指针构造函数创建的 std::shared_ptr 共享所有权。
上面的描述性代码中的测试 ptr->weak_this.expired() 确保如果 weak_this
已经指示了一个所有者,则不会重新分配 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) |
[edit] 示例
#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
[edit] 另请参阅
构造新的 shared_ptr (公有成员函数) | |
创建一个管理新对象的共享指针 (函数模板) |