C++ 参考手册
- C++11
- C++14
- C++17
- C++20
- C++ 编译器支持情况表
- 独立与宿主实现
- C++ 语言
- C++ 关键词
- 预处理器
- C++ 标准库头文件
- 具名要求
- 功能特性测试 (C++20)
- 工具库
- 类型支持(基本类型、RTTI、类型特性)
- 概念库 (C++20)
- 错误处理
- 动态内存管理
- std::unique_ptr
- std::scoped_allocator_adaptor
- std::auto_ptr
- std::destroy_at
- std::destroy
- std::destroy_n
- std::uninitialized_move
- std::uninitialized_value_construct
- std::owner_less
- std::shared_ptr
- std::allocate_shared, std::allocate_shared_for_overwrite
- std::make_shared, std::make_shared_for_overwrite
- std::atomic(std::shared_ptr)
- std::hash(std::shared_ptr)
- std::atomic_...<std::shared_ptr>
- std::addressof
- std::allocator_traits
- std::default_delete
- std::allocator_arg_t
- std::allocator_arg
- std::weak_ptr
- std::enable_shared_from_this
- std::bad_weak_ptr
- std::to_address
- std::assume_aligned
- std::make_obj_using_allocator
- C 内存管理库
- 低层内存管理
- std::pmr::memory_resource
- std::allocator
- std::pointer_traits
- std::uses_allocator
- std::uses_allocator_construction_args
- std::uninitialized_construct_using_allocator
- std::pmr::polymorphic_allocator
- std::pmr::get_default_resource
- std::pmr::set_default_resource
- std::pmr::new_delete_resource
- std::pmr::null_memory_resource
- std::pmr::synchronized_pool_resource
- std::pmr::unsynchronized_pool_resource
- std::pmr::monotonic_buffer_resource
- std::pmr::pool_options
- std::raw_storage_iterator
- std::get_temporary_buffer
- std::return_temporary_buffer
- std::uninitialized_copy
- std::uninitialized_fill
- std::uninitialized_default_construct
- std::uninitialized_copy_n
- std::uninitialized_fill_n
- std::uninitialized_move_n
- std::uninitialized_default_construct_n
- std::uninitialized_value_construct_n
- std::construct_at
- std::align
- 注释
- 日期和时间工具
- 字符串库
- 容器库
- 迭代器库
- 范围库 (C++20)
- 算法库
- 数值库
- 输入/输出库
- 文件系统库
- 本地化库
- 正则表达式库
- 原子操作库
- 线程支持库
- 实验性 C++ 特性
- 有用的资源
- 索引
- std 符号索引
- 协程支持 (C++20)
- C++ 关键词
位置:首页 > C++ 参考手册 >动态内存管理 >std::shared_ptr > std::make_shared, std::make_shared_for_overwrite
std::make_shared, std::make_shared_for_overwrite
定义于头文件 <memory>
|
||
template< class T, class... Args > shared_ptr<T> make_shared( Args&&... args ); |
(1) | (C++11 起) (T 非数组) |
template<class T> shared_ptr<T> make_shared( std::size_t N ); |
(2) | (C++20 起) (T 为 U[]) |
template<class T> shared_ptr<T> make_shared(); |
(3) | (C++20 起) (T 为 U[N]) |
template<class T> shared_ptr<T> make_shared( std::size_t N, const std::remove_extent_t<T>& u ); |
(4) | (C++20 起) (T 为 U[]) |
template<class T> shared_ptr<T> make_shared( const std::remove_extent_t<T>& u ); |
(5) | (C++20 起) (T 为 U[N]) |
template<class T> shared_ptr<T> make_shared_for_overwrite(); |
(6) | (C++20 起) (T 非 U[]) |
template<class T> shared_ptr<T> make_shared_for_overwrite( std::size_t N ); |
(7) | (C++20 起) (T 为 U[]) |
1) 以
args
为 T
的构造函数参数列表,构造 T
类型对象并将它包装于 std::shared_ptr 。对象如同用表达式 ::new (pv) T(std::forward<Args>(args)...) 构造,其中 pv
是内部指向适合保有 T
类型对象的存储的 void*
指针。存储典型地大于 sizeof(T)
,以对共享指针控制块和 T
对象使用一次分配。此函数所调用的 std::shared_ptr
构造函数以指向新构造的 T
类型对象指针启用 shared_from_this
。此重载仅若 T 不是数组类型才参与重载决议。2,3) 同 (1) ,但构造的对象是可能多维的数组,其
std::remove_all_extents_t<T>
类型的非数组元素如同以布置 new 表达式 ::new(pv) std::remove_all_extents_t<T>() 值初始化。重载 (2) 创建第一维上大小为 N
的数组。数组元素以其地址递增顺序初始化,而当其生存期结束时,以原本构造顺序的逆序销毁。4,5) 同 (2,3) ,但每个元素从默认值
u
初始化。若 U
不是数组类型,则这如同以如 (1) 中的布置 new 表达式进行;否则,这如同以如同 (1) 中的布置 new 表达式,从来自 u
的对应元素初始化(可能多维的)数组的每个非数组元素。重载 (4) 创建第一维上大小为 N
的数组。数组元素以其地址递增顺序初始化,而当其生存期结束时,以原本构造顺序的逆序销毁。每种情况下,均将用 p->~X() 销毁对象(或若 T
为数组类型则为单独的元素) (C++20 起),其中 p
是指向对象的指针,而 X
是该对象的类型。
参数
args | - | 将用以构造 T 实例的参数列表。
|
N | - | 要使用的数组 |
u | - | 初始化数组每个元素的初值 |
返回值
类型 T
实例的 std::shared_ptr 。
异常
可能抛出 std::bad_alloc 或任何 T
构造函数所抛的异常。若抛出异常,则函数无效果。若异常在数组的构造中抛出,则已初始化元素以逆序销毁。 (C++20 起)
注解
此函数可用作 std::shared_ptr<T>(new T(args...)) 的替代品。得失是:
- std::shared_ptr<T>(new T(args...)) 进行至少二次分配(一次为
T
而另一次为共享指针的控制块),而 std::make_shared<T> 典型地仅进行一次分配(标准推荐但不要求如此,所有已知实现均如此)。 - 若任何 std::weak_ptr 在所有共享拥有者的生存期结束后引用
std::make_shared
所创建的控制块,则T
所占有的内存维持着,直至所有弱拥有者亦被销毁,若sizeof(T)
较大则这可能是不想要的。 - std::shared_ptr<T>(new T(args...)) 可能调用
T
的非公开构造函数,若在它可访问的语境中执行,而std::make_shared
要求对被选择构造函数的公开访问。 - 不同于 std::shared_ptr 构造函数,
std::make_shared
不允许自定义删除器。 -
std::make_shared
使用 ::new ,故若用类特定的 operator new 设置了任何特殊行为,则它将异于 std::shared_ptr<T>(new T(args...)) 。
|
(C++20 前) |
|
(C++17 前) |
构造函数以 U*
类型指针 ptr
启用 shared_from_this
,表示它确定 U
是否拥有作为 std::enable_shared_from_this 特化的无歧义且可访问 (C++17 起)基类,而若如此,则构造函数求值该语句:
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::shared_from_this 的隐藏 mutable std::weak_ptr
成员。对 weak_this
成员的赋值不是原子的,且与任何到同一对象的潜在并发访问冲突。这确保将来对 shared_from_this() 调用,将与此裸指针构造函数所创建的 shared_ptr
共享所有权。
上述解释代码中,测试 ptr->weak_this.expired()
是为确保若 weak_this
指示已有占有者则重赋值它。从 C++17 起要求此测试。
示例
运行此代码
#include <iostream> #include <memory> #include <type_traits> struct C { C(int i) : i(i) {} // < 需要构造函数 (C++20 前) int i; }; int main() { auto sp = std::make_shared<C>(12); static_assert(std::is_same_v<decltype(sp), std::shared_ptr<C>>); std::cout << sp->i << '\n'; }
输出:
12
参阅
构造新的 shared_ptr (公开成员函数) | |
创建管理一个用分配器分配的新对象的共享指针 (函数模板) | |
(C++14)(C++20) |
创建管理一个新对象的独占指针 (函数模板) |
分配函数 (函数) |