std::shared_ptr

来自cppreference.com
< cpp‎ | memory
 
 
实用工具库
类型的支持 (basic types, RTTI, type traits)
动态内存管理
错误处理
程序实用工具
可变参数函数
日期和时间
函数对象
initializer_list(C++11)
bitset
hash(C++11)
关系运算符
原文:
Relational operators
这段文字是通过 Google Translate 自动翻译生成的。
您可以帮助我们检查、纠正翻译中的错误。详情请点击这里
rel_ops::operator!=
rel_ops::operator>
rel_ops::operator<=
rel_ops::operator>=
双和元组
原文:
Pairs and tuples
这段文字是通过 Google Translate 自动翻译生成的。
您可以帮助我们检查、纠正翻译中的错误。详情请点击这里
pair
tuple(C++11)
piecewise_construct_t(C++11)
piecewise_construct(C++11)
掉期,远期和移动
原文:
Swap, forward and move
这段文字是通过 Google Translate 自动翻译生成的。
您可以帮助我们检查、纠正翻译中的错误。详情请点击这里
swap
forward(C++11)
move(C++11)
move_if_noexcept(C++11)
declval(C++11)
 
动态内存管理
低级别的内存管理
分配器
原文:
Allocators
这段文字是通过 Google Translate 自动翻译生成的。
您可以帮助我们检查、纠正翻译中的错误。详情请点击这里
allocator
allocator_traits(C++11)
allocator_arg_t(C++11)
allocator_arg(C++11)
uses_allocator(C++11)
scoped_allocator_adaptor(C++11)
未初始化的存储空间
原文:
Uninitialized storage
这段文字是通过 Google Translate 自动翻译生成的。
您可以帮助我们检查、纠正翻译中的错误。详情请点击这里
uninitialized_copy
uninitialized_copy_n(C++11)
uninitialized_fill
uninitialized_fill_n
raw_storage_iterator
get_temporary_buffer
return_temporary_buffer
智能指针
原文:
Smart pointers
这段文字是通过 Google Translate 自动翻译生成的。
您可以帮助我们检查、纠正翻译中的错误。详情请点击这里
unique_ptr(C++11)
shared_ptr(C++11)
weak_ptr(C++11)
auto_ptr(已弃用)
owner_less(C++11)
enable_shared_from_this(C++11)
bad_weak_ptr(C++11)
default_delete(C++11)
垃圾收集的支持
原文:
Garbage collection support
这段文字是通过 Google Translate 自动翻译生成的。
您可以帮助我们检查、纠正翻译中的错误。详情请点击这里
declare_reachable(C++11)
undeclare_reachable(C++11)
declare_no_pointers(C++11)
undeclare_no_pointers(C++11)
pointer_safety(C++11)
get_pointer_safety(C++11)
杂项
原文:
Miscellaneous
这段文字是通过 Google Translate 自动翻译生成的。
您可以帮助我们检查、纠正翻译中的错误。详情请点击这里
pointer_traits(C++11)
addressof(C++11)
align(C++11)
C库
原文:
C Library
这段文字是通过 Google Translate 自动翻译生成的。
您可以帮助我们检查、纠正翻译中的错误。详情请点击这里
 
std::shared_ptr
成员函数
原文:
Member functions
这段文字是通过 Google Translate 自动翻译生成的。
您可以帮助我们检查、纠正翻译中的错误。详情请点击这里
shared_ptr::shared_ptr
shared_ptr::~shared_ptr
shared_ptr::operator=
修饰符
原文:
Modifiers
这段文字是通过 Google Translate 自动翻译生成的。
您可以帮助我们检查、纠正翻译中的错误。详情请点击这里
shared_ptr::reset
shared_ptr::swap
观察员
原文:
Observers
这段文字是通过 Google Translate 自动翻译生成的。
您可以帮助我们检查、纠正翻译中的错误。详情请点击这里
shared_ptr::get
shared_ptr::operator*
shared_ptr::operator->
shared_ptr::use_count
shared_ptr::unique
shared_ptr::operator bool
shared_ptr::owner_before
非成员函数
原文:
Non-member functions
这段文字是通过 Google Translate 自动翻译生成的。
您可以帮助我们检查、纠正翻译中的错误。详情请点击这里
std::swap
make_shared
allocate_shared
static_pointer_cast
dynamic_pointer_cast
const_pointer_cast
get_deleter
operator==
operator|=
operator<
operator<=
operator>
operator>=
operator<<
atomic_is_lock_free
atomic_load
atomic_load_explicit
atomic_store
atomic_store_explicit
atomic_exchange
atomic_exchange_explicit
atomic_compare_exchange_weak
atomic_compare_exchange_strong
atomic_compare_exchange_weak_explicit
atomic_compare_exchange_strong_explicit
std::hash
 
在头文件 <memory> 中定义
template< class T > class shared_ptr;
(since C++11)

std::shared_ptr 是通过指针保持某个对象的共享拥有权的智能指针。若干个 shared_ptr 对象可以拥有同一个对象;最后一个指向该对象的 shared_ptr 被销毁或重置时,该对象被销毁。销毁该对象时使用的是 delete 表达式或者是在构造 shared_ptr 时传入的自定义删除器(deleter)。

shared_ptr 也可以不拥有对象,称作空(empty)

shared_ptr 满足 CopyConstructibleCopyAssignable 的要求。

目录

[编辑] 成员类型

成员类型 定义
element_type T

[编辑] 成员函数

构造新的 shared_ptr
(公共成员函数) [edit]
如果没有更多shared_ptr指向持有的对象,则析构对象
(公共成员函数) [edit]
shared_ptr赋值
(公共成员函数) [edit]
修饰符
替换所管理的对象
(公共成员函数) [edit]
交换所管理的对象
(公共成员函数) [edit]
观察器
返回指向被管理对象的指针
(公共成员函数) [edit]
提领指向被管理对象的指针
(公共成员函数) [edit]
返回shared_ptr所指对象的引用计数
(公共成员函数) [edit]
检查所管理对象是否仅由当前shared_ptr的实例管理
(公共成员函数) [edit]
检查是否有关联的管理对象
(公共成员函数) [edit]
提供基于拥有者的共享指针排序
(公共成员函数) [edit]

[编辑] 非成员函数

从参数创建并返回shared_ptr,便于类型推断
(函数模板) [edit]
创建一个共享指针来管理使用分配器分配的新对象
(函数模板) [edit]
对被管理对象的类型应用static_castdynamic_castconst_cast
(函数模板) [edit]
返回指定类型的删除器,如果拥有的话
(函数模板) [edit]
与另一个shared_ptrnullptr比较
(函数模板) [edit]
将所管理指针的值输出到输出流中
(函数模板) [edit]
特化的std::swap算法
(函数模板) [edit]
特化的原子操作
(函数模板) [edit]

[编辑] 辅助类

支持std::shared_ptr的哈希函数
(类模板特化) [edit]

[编辑] 实现说明

在典型的实现中,std::shared_ptr 只保存两个指针:

  • 指向被管理对象的指针
  • 指向控制块(control block)的指针

控制块是一个动态分配的对象,其中包含:

  • 指向被管理对象的指针或被管理对象本身
  • 删除器
  • 分配器(allocator)
  • 拥有被管理对象的 shared_ptr 的数量
  • 引用被管理对象的 weak_ptr 的数量

通过 std::make_sharedstd::allocate_shared 创建 shared_ptr 时,控制块将被管理对象本身作为其数据成员;而通过构造函数创建 shared_ptr 时则保存指针。

shared_ptr 持有的指针是通过 get() 返回的;而控制块所持有的指针/对象则是最终引用计数归零时会被删除的那个。两者并不一定相等。

shared_ptr 的析构函数会将控制块中的 shared_ptr 计数器减一,如果减至零,控制块就会调用被管理对象的析构函数。但控制块本身直到 std::weak_ptr 计数器同样归零时才会释放。

[编辑] 例子

#include <iostream>
#include <memory>
#include <thread>
#include <chrono>
#include <mutex>
 
struct Base
{
    Base() { std::cout << "  Base::Base()\n"; }
    // 注意:这里可以使用非虚的析构器
    ~Base() { std::cout << "  Base::~Base()\n"; }
};
 
struct Derived: public Base
{
    Derived() { std::cout << "  Derived::Derived()\n"; }
    ~Derived() { std::cout << "  Derived::~Derived()\n"; }
};
 
void thr(std::shared_ptr<Base> p)
{
    std::this_thread::sleep_for(std::chrono::seconds(1));
    std::shared_ptr<Base> lp = p; // 类型安全,即使
                                  // 共享的 use_count 增加
    {
        static std::mutex io_mutex;
        std::lock_guard<std::mutex> lk(io_mutex);
        std::cout << "local pointer in a thread:\n"
                  << "  lp.get() = " << lp.get()
                  << ", lp.use_count() = " << lp.use_count() << '\n';
    }
}
 
int main()
{
    std::shared_ptr<Base> p = std::make_shared<Derived>();
 
    std::cout << "Created a shared Derived (as a pointer to Base)\n"
              << "  p.get() = " << p.get()
              << ", p.use_count() = " << p.use_count() << '\n';
    std::thread t1(thr, p), t2(thr, p), t3(thr, p);
    p.reset(); // 从 main 中释放所有权
    std::cout << "Shared ownership between 3 threads and released\n"
              << "ownership from main:\n"
              << "  p.get() = " << p.get()
              << ", p.use_count() = " << p.use_count() << '\n';
    t1.join(); t2.join(); t3.join();
    std::cout << "All threads completed, the last one deleted Derived\n";
}

可能的输出:

Base::Base()
  Derived::Derived()
Created a shared Derived (as a pointer to Base)
  p.get() = 0xc99028, p.use_count() = 1
Shared ownership between 3 threads and released
ownership from main:
  p.get() = (nil), p.use_count() = 0
local pointer in a thread:
  lp.get() = 0xc99028, lp.use_count() = 3
local pointer in a thread:
  lp.get() = 0xc99028, lp.use_count() = 4
local pointer in a thread:
  lp.get() = 0xc99028, lp.use_count() = 2
  Derived::~Derived()
  Base::~Base()
All threads completed, the last one deleted Derived