首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

std::shared_ptr

Defined in header <memory>

?

?

template< class T > class shared_ptr;

?

(since C++11)

std::shared_ptr是通过指针保留对象共享所有权的智能指针。几个shared_ptr对象可以拥有相同的对象。当发生下列任何一种情况时,该对象将被销毁,其内存将被释放:

  • 最后的余生shared_ptr拥有物品被销毁;
  • 最后的余生shared_ptr拥有该对象将通过以下方式分配另一个指针operator=reset()...

使用delete-expression或自定义删除器提供给shared_ptr在建筑过程中。

shared_ptr可以在存储指向另一个对象的指针时共享对象的所有权。此功能可用于在拥有成员对象所属对象时指向成员对象。存储的指针是get()、取消引用和比较操作符。托管指针是在使用计数达到零时传递给删除器的指针。

shared_ptr也不可能拥有任何对象,在这种情况下,它被调用。空空%28 a空共享[医]如果使用别名构造函数来创建%29,则PTR可能有一个非空存储指针。

所有的专门化shared_ptr满足…的要求CopyConstructible,,,CopyAssignable,和LessThanComparable而且是上下文可转换到bool...

所有成员函数%28,包括复制构造函数和副本分配%29,可以由多个线程在shared_ptr即使这些实例是同一个对象的副本和共享所有权,也不需要额外的同步。如果多个执行线程访问相同的shared_ptr没有同步的情况下,任何这些访问都使用非const成员函数。shared_ptr则会发生数据竞争;共享[医]原子函数的PTR过载可用于防止数据竞争。

成员类型

Member type

Definition

element_type

T (until C++17) std::remove_extent_t<T> (since C++17)

T

(until C++17)

std::remove_extent_t<T>

(since C++17)

T

(until C++17)

std::remove_extent_t<T>

(since C++17)

weak_type (since C++17)

std::weak_ptr<T>

成员函数

(constructor)

constructs new shared_ptr (public member function)

(destructor)

destructs the owned object if no more shared_ptrs link to it (public member function)

operator=

assigns the shared_ptr (public member function)

修饰符

重置替换托管对象%28公共成员函数%29

交换托管对象%28公共成员函数%29

观察员

GET返回存储的指针%28公共成员函数%29

操作者%2A运算符->取消存储的指针%28公共成员函数%29

操作者提供对存储的数组%28公共成员函数%29的索引访问

使用[医]计数返回共享的数目。[医]引用同一个托管对象%28公共成员函数%29的PTR对象

唯一%28不推荐%29检查托管对象是否仅由当前共享管理[医]PTR实例%28公共成员函数%29

操作符bool检查存储的指针是否为空%28公共成员函数%29。

业主[医]提供共享指针%28公共成员函数%29的基于所有者的排序。

非会员职能

make_shared

creates a shared pointer that manages a new object (function template)

allocate_shared

creates a shared pointer that manages a new object allocated using an allocator (function template)

static_pointer_castdynamic_pointer_castconst_pointer_castreinterpret_pointer_cast (C++17)

applies static_cast, dynamic_cast, const_cast, or reinterpret_cast to the stored pointer (function template)

get_deleter

returns the deleter of specified type, if owned (function template)

operator==operator!=operator<operator<=operator>operator>=

compares with another shared_ptr or with nullptr (function template)

operator<<

outputs the value of the stored pointer to an output stream (function template)

std::swap(std::shared_ptr) (C++11)

specializes the std::swap algorithm (function template)

std::atomic_is_lock_free(std::shared_ptr)std::atomic_load(std::shared_ptr)std::atomic_load_explicit(std::shared_ptr)std::atomic_store(std::shared_ptr)std::atomic_store_explicit(std::shared_ptr)std::atomic_exchange(std::shared_ptr)std::atomic_exchange_explicit(std::shared_ptr)std::atomic_compare_exchange_weak(std::shared_ptr)std::atomic_compare_exchange_strong(std::shared_ptr)std::atomic_compare_exchange_weak_explicit(std::shared_ptr)std::atomic_compare_exchange_strong_explicit(std::shared_ptr)

specializes atomic operations for std::shared_ptr (function template)

帮助者类

std::hash<std::shared_ptr> (C++11)

hash support for std::shared_ptr (class template specialization)

注记

对象的所有权只能与另一个对象共享。shared_ptr通过复制构造或复制将其值分配给另一个shared_ptr.建造一个新的shared_ptr使用另一个用户拥有的原始基础指针shared_ptr导致行为不明。

std::shared_ptr可以与不完全类型T但是,来自原始指针%28的构造函数template<class Y> shared_ptr(Y*)%29template<class Y> void reset(Y*)成员函数只能通过指向完整类型%28的指针调用,std::unique_ptr可以从指向不完整类型%29的原始指针构造。

执行说明

在一个典型的实现中,std::shared_ptr只包含两个指针:

  • 返回的存储指针%281get()29%;
  • 指向控制块...

控制块是一个动态分配的对象,它保存:

  • 指向托管对象或托管对象本身的指针;
  • 删除%28类型-删除%29;
  • 分配器%28类型-擦除%29;
  • 的数目shared_ptrs拥有托管对象;
  • 的数目weak_ptrs引用托管对象。

何时shared_ptr是通过调用std::make_sharedstd::allocate_shared,控制块和托管对象的内存都是用单个分配创建的。托管对象是在控制块的数据成员中就地构造的.。何时shared_ptr是通过shared_ptr构造函数、托管对象和控制块必须分开分配。在这种情况下,控制块存储指向托管对象的指针。

对象持有的指针。shared_ptr直接返回的是get(),而控制块持有的指针/对象是当共享所有者数达到零时将被删除的指针/对象。这些指针不一定相等。

破坏者shared_ptr减少控制块的共享所有者的数量。如果计数器达到零,则控制块调用托管对象的析构函数。控件块直到std::weak_ptr计数器也达到零。

在实际实现中,弱指针的数量可能增加如果有指向同一控制块的共享指针。

为了满足线程安全要求,引用计数器通常使用等效的std::atomic::fetch_add带着std::memory_order_relaxed%28递减需要更强的排序才能安全地销毁控制块%29。

二次

代码语言:javascript
复制
#include <iostream>
#include <memory>
#include <thread>
#include <chrono>
#include <mutex>
 
struct Base
{
    Base() { std::cout << "  Base::Base()\n"; }
    // Note: non-virtual destructor is OK here
    ~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; // thread-safe, even though the
                                  // shared use_count is incremented
    {
        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(); // release ownership from 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";
}

二次

可能的产出:

二次

代码语言:javascript
复制
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

二次

代码语言:txt
复制
 ? cppreference.com

在CreativeCommonsAttribution下授权-ShareAlike未移植许可v3.0。

扫码关注腾讯云开发者

领取腾讯云代金券

http://www.vxiaotou.com