std::shared_ptr<T>:: shared_ptr
| 
           
            
             constexpr
            
            shared_ptr
            
             (
            
            
             )
            
            
             noexcept
            
            
             ;
            
           
           | (1) | |
| 
           
            
             constexpr
            
            shared_ptr
            
             (
            
            
             
              std::
              
               nullptr_t
              
             
            
            
             )
            
            
             noexcept
            
            
             ;
            
           
           | (2) | |
| 
           
            
             template
            
            
             <
            
            
             class
            
            Y
            
             >
            
             explicit shared_ptr ( Y * ptr ) ; | (3) | |
| 
           
            
             template
            
            
             <
            
            
             class
            
            Y,
            
             class
            
            Deleter
            
             >
            
             shared_ptr ( Y * ptr, Deleter d ) ; | (4) | |
| 
           
            
             template
            
            
             <
            
            
             class
            
            Deleter
            
             >
            
             shared_ptr ( std:: nullptr_t ptr, Deleter d ) ; | (5) | |
| 
           
            
             template
            
            
             <
            
            
             class
            
            Y,
            
             class
            
            Deleter,
            
             class
            
            Alloc
            
             >
            
             shared_ptr ( Y * ptr, Deleter d, Alloc alloc ) ; | (6) | |
| 
           
            
             template
            
            
             <
            
            
             class
            
            Deleter,
            
             class
            
            Alloc
            
             >
            
             shared_ptr ( std:: nullptr_t ptr, Deleter d, Alloc alloc ) ; | (7) | |
| 
           
            
             template
            
            
             <
            
            
             class
            
            Y
            
             >
            
             shared_ptr ( const shared_ptr < Y > & r, element_type * ptr ) noexcept ; | (8) | |
| 
           
            
             template
            
            
             <
            
            
             class
            
            Y
            
             >
            
             shared_ptr ( shared_ptr < Y > && r, element_type * ptr ) noexcept ; | (8) | (自 C++20 起) | 
| 
           
            shared_ptr
            
             (
            
            
             const
            
            shared_ptr
            
             &
            
            r
            
             )
            
            
             noexcept
            
            
             ;
            
           
           | (9) | |
| 
           
            
             template
            
            
             <
            
            
             class
            
            Y
            
             >
            
             shared_ptr ( const shared_ptr < Y > & r ) noexcept ; | (9) | |
| 
           
            shared_ptr
            
             (
            
            shared_ptr
            
             &&
            
            r
            
             )
            
            
             noexcept
            
            
             ;
            
           
           | (10) | |
| 
           
            
             template
            
            
             <
            
            
             class
            
            Y
            
             >
            
             shared_ptr ( shared_ptr < Y > && r ) noexcept ; | (10) | |
| 
           
            
             template
            
            
             <
            
            
             class
            
            Y
            
             >
            
             explicit shared_ptr ( const std:: weak_ptr < Y > & r ) ; | (11) | |
| 
           
            
             template
            
            
             <
            
            
             class
            
            Y
            
             >
            
             shared_ptr ( std:: auto_ptr < Y > && r ) ; | (12) | (在 C++17 中移除) | 
| 
           
            
             template
            
            
             <
            
            
             class
            
            Y,
            
             class
            
            Deleter
            
             >
            
             shared_ptr ( std:: unique_ptr < Y, Deleter > && r ) ; | (13) | |
       从多种指针类型构造新的
       
        shared_ptr
       
       ,这些指针指向需要管理的对象。
      
| 
          为便于下文描述,当满足以下任一条件时,称指针类型
           | (since C++17) | 
        shared_ptr
       
       ,即空
       
        shared_ptr
       
       。
      
        shared_ptr
       
       。
       | 
           对于
           
            (3,4,6)
           
           ,
            | (C++17 前) | 
| 
           若
            | (C++17 起) | 
          T
         
         不是数组类型);
         
          
           delete
           
            [
           
           
            ]
           
           ptr
          
         
         (若
         
          T
         
         是数组类型)
        
        
         
          (C++17 起)
         
        
       
       作为删除器。
       
        Y
       
       必须是完整类型。该 delete 表达式必须格式正确、具有明确定义的行为且不抛出任何异常。
       
        
         此构造函数额外不参与重载决议,若 delete 表达式格式不正确。
        
        
         
          (C++17 起)
         
        
       
      | 
            | (C++17 前) | 
| 如果表达式 d ( ptr ) 格式不正确,或如果 std:: is_move_constructible_v < D > 为 false ,则这些构造函数额外不参与重载决议。 | (C++17 起) | 
        shared_ptr
       
       。若此
       
        shared_ptr
       
       是组中最后一个离开作用域的,它将调用最初由
       
        
         r
        
       
       管理的对象所存储的删除器。然而,对此
       
        shared_ptr
       
       调用
       
        get()
       
       将始终返回
       
        
         ptr
        
       
       的副本。程序员需确保在此 shared_ptr 存续期间
       
        
         ptr
        
       
       保持有效,例如在典型使用场景中:
       
        
         ptr
        
       
       是由
       
        
         r
        
       
       管理的对象的成员,或是
       
        r.get()
       
       的别名(如下行转换)
       
        
         对于接受右值的第二个重载,调用后
         
          
           r
          
         
         为空且
         
          
           r.
           
            get
           
           
            (
           
           
            )
           
           
            ==
           
           nullptr
          
         
         。
        
        
         
          (C++20 起)
         
        
       
      
        shared_ptr
       
       。若
       
        
         r
        
       
       未管理任何对象,则
       
        
         
          *
         
         this
        
       
       亦不管理任何对象。当
       
        Y*
       
       不能
       
        
         隐式转换为
        
        
         
          (C++17 前)
         
        
       
       
        
         
          兼容
         
        
        
         
          (C++17 起)
         
        
       
       
        T*
       
       时,该模板重载不参与重载决议。
      
        shared_ptr
       
       。构造完成后,
       
        
         
          *
         
         this
        
       
       包含
       
        
         r
        
       
       先前状态的副本,
       
        
         r
        
       
       变为空且其存储的指针为 null。若
       
        Y*
       
       不能
       
        
         隐式转换为
        
        
         
          (C++17 前)
         
        
       
       
        
         
          与
         
        
        
         
          (C++17 起)
         
        
       
       
        T*
       
       兼容,则该模板重载不参与重载决议。
      
        shared_ptr
       
       。
       
        
         
          Y*
         
         必须可隐式转换为
         
          T*
         
         。
        
        
         
          (C++17 前)
         
        
       
       
        
         此重载仅在
         
          Y*
         
         与
         
          T*
         
         兼容时参与重载决议。
        
        
         
          (C++17 起)
         
        
       
       注意
       
        
         r.
         
          lock
         
         
          (
         
         
          )
         
        
       
       可用于相同目的:区别在于当参数为空时,该构造函数会抛出异常,而
       
        
         
          
           std::
           
            weak_ptr
           
          
         
         
          <
         
         T
         
          >
         
         
          ::
         
         
          lock
         
         
          (
         
         
          )
         
        
       
       在这种情况下会构造一个空的
       
        std::shared_ptr
       
       。
      
        shared_ptr
       
       。
       
        Y*
       
       必须可转换为
       
        T*
       
       。构造完成后,
       
        
         r
        
       
       变为空。
      
        shared_ptr
       
       。与
       
        
         r
        
       
       关联的删除器将被存储用于未来删除被管理对象。调用后
       
        
         r
        
       
       不再管理任何对象。
       | 如果 
           std::unique_ptr<Y, Deleter>::pointer
          与
           T*
          不兼容,此重载不参与重载决议。
如果
          
           
            r.
            
             get
            
            
             (
            
            
             )
            
           
          
          是空指针,此重载等价于默认构造函数
          
           (1)
          
          。 | (C++17 起) | 
        Deleter
       
       是引用类型,则等价于
       
        
         shared_ptr
         
          (
         
         r.
         
          release
         
         
          (
         
         
          )
         
         ,
         
          
           std::
           
            ref
           
          
         
         
          (
         
         r.
         
          get_deleter
         
         
          (
         
         
          )
         
         
          )
         
        
       
       。否则等价于
       
        
         shared_ptr
         
          (
         
         r.
         
          release
         
         
          (
         
         
          )
         
         , std
         
          ::
         
         
          move
         
         
          (
         
         r.
         
          get_deleter
         
         
          (
         
         
          )
         
         
          )
         
         
          )
         
        
       
       。
      
       当
       
        T
       
       不是数组类型时,重载
       
        (3,4,6)
       
       允许通过
       
        
         ptr
        
       
       使用
       
        shared_from_this
       
       ,而重载
       
        (13)
       
       允许通过
       
        
         r.
         
          release
         
         
          (
         
         
          )
         
        
       
       返回的指针使用
       
        shared_from_this
       
       。
      
| 目录 | 
参数
| ptr | - | 指向要管理的对象的指针 | 
| d | - | 用于销毁对象的删除器 | 
| alloc | - | 用于内部数据分配的内存分配器 | 
| r | - | 用于共享所有权或获取所有权的另一个智能指针 | 
后置条件
异常
        T
       
       不是数组类型时调用
       
        
         delete ptr
        
       
       
        
         ,否则调用
         
          
           delete
           
            [
           
           
            ]
           
           ptr
          
         
        
        
         
          (C++17 起)
         
        
       
       。
      注释
       构造函数通过类型为
       
        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 起成为必需。
      
       原始指针的重载版本会接管所指对象的所有权。因此,若对已被
       
        shared_ptr
       
       管理的对象使用原始指针重载构造
       
        shared_ptr
       
       (例如通过
       
        
         shared_ptr
         
          (
         
         ptr.
         
          get
         
         
          (
         
         
          )
         
         
          )
         
        
       
       ),即使该对象继承自
       
        
         std::enable_shared_from_this
        
       
       ,仍可能导致未定义行为。
      
       由于默认构造函数是
       
        constexpr
       
       的,静态 shared_ptr 会作为
       
        静态非局部初始化
       
       的一部分,在任何动态非局部初始化开始之前完成初始化。这使得在任何静态对象的构造函数中使用 shared_ptr 都是安全的。
      
在 C++11 和 C++14 中,可以从 std:: unique_ptr < T [ ] > 构造 std:: shared_ptr < T > :
std::unique_ptr<int[]> arr(new int[1]); std::shared_ptr<int> ptr(std::move(arr));
       由于
       
        shared_ptr
       
       从其
       
        
         std::unique_ptr
        
       
       获取删除器(一个
       
        
         
          
           std::
           
            default_delete
           
          
         
         
          <
         
         T
         
          [
         
         
          ]
         
         
          >
         
        
       
       对象),该数组将被正确释放。
      
这在 C++17 中不再被允许。应改用数组形式 std:: shared_ptr < T [ ] > 。
示例
#include <iostream> #include <memory> struct Foo { int id{0}; Foo(int i = 0) : id{i} { std::cout << "Foo::Foo(" << i << ")\n"; } ~Foo() { std::cout << "Foo::~Foo(), id=" << id << '\n'; } }; struct D { void operator()(Foo* p) const { std::cout << "Call delete from function object. Foo::id=" << p->id << '\n'; delete p; } }; int main() { { std::cout << "1) constructor with no managed object\n"; std::shared_ptr<Foo> sh1; } { std::cout << "2) constructor with object\n"; std::shared_ptr<Foo> sh2(new Foo{10}); std::cout << "sh2.use_count(): " << sh2.use_count() << '\n'; std::shared_ptr<Foo> sh3(sh2); std::cout << "sh2.use_count(): " << sh2.use_count() << '\n'; std::cout << "sh3.use_count(): " << sh3.use_count() << '\n'; } { std::cout << "3) constructor with object and deleter\n"; std::shared_ptr<Foo> sh4(new Foo{11}, D()); std::shared_ptr<Foo> sh5(new Foo{12}, [](auto p) { std::cout << "Call delete from lambda... p->id=" << p->id << '\n'; delete p; }); } }
输出:
1) constructor with no managed object 2) constructor with object Foo::Foo(10) sh2.use_count(): 1 sh2.use_count(): 2 sh3.use_count(): 2 Foo::~Foo(), id=10 3) constructor with object and deleter Foo::Foo(11) Foo::Foo(12) Call delete from lambda... p->id=12 Foo::~Foo(), id=12 Call delete from function object. Foo::id=11 Foo::~Foo(), id=11
缺陷报告
下列行为变更缺陷报告被追溯应用于先前发布的 C++ 标准。
| 缺陷报告 | 应用于 | 发布时的行为 | 正确行为 | 
|---|---|---|---|
| LWG 3548 | C++11 | 来自 
          unique_ptr
         的构造函数对删除器进行了复制构造 | 改为移动构造 | 
参见
| 创建管理新对象的共享指针 (函数模板) | |
| 创建使用分配器分配新对象的共享指针 (函数模板) | |
| 
           
            
             
              (C++11)
             
            
           
           | 允许对象创建指向自身的 
          shared_ptr
         (类模板) |