c++11 智能指针 (std::shared_ptr)(二)

 定义于头文件 <memory>

 

template< class T > class shared_ptr;     (C++11 起) 

 析构函数

std::shared_ptr<T>::~shared_ptr
~shared_ptr();

*this 占有对象且它是最后一个占有该对象的 shared_ptr ,则通过占有的删除器销毁对象。

析构后,与 *this 共享所有权的智能指针若存在,则报告比先前值少一的 use_count() 。

注意

不同于 std::unique_ptr ,即使被管理指针为空也调用 std::shared_ptr 的删除器。

对 shared_ptr 赋值

std::shared_ptr<T>::operator=
shared_ptr& operator=( const shared_ptr& r ) noexcept;(1)  

template< class Y >shared_ptr& operator=( const shared_ptr<Y>& r ) noexcept;(1)  

shared_ptr& operator=( shared_ptr&& r ) noexcept;(2)  

template< class Y >
shared_ptr& operator=( shared_ptr<Y>&& r ) noexcept;(2)  

template< class Y >shared_ptr& 
operator=( std::auto_ptr<Y>&& r );(3) (C++11 中弃用)(C++17 中移除) 

template< class Y, class Deleter >
shared_ptr& operator=( std::unique_ptr<Y,Deleter>&& r );(4) 

r 所管理者替换被管理对象。

*this 已占有对象且它是最后一个占有该对象的 shared_ptr ,且 r*this 不相同,则通过占有的删除器销毁对象。

1) 共享 r 所管理对象的所有权。若 r 不管理对象,则 *this 亦不管理对象。等价于 shared_ptr<T>(r).swap(*this) 。

2) 从 r 移动赋值 shared_ptr 。赋值后, *this 含有先前 r 状态的副本,而 r 为空,等价于 shared_ptr<T>(std::move(r)).swap(*this) 。

3) 转移 r 所管理对象的所有权给 *this 。若 r 不管理对象,则 *this 亦不管理对象。赋值后, *this 含有先前 r 所保有的对象,且 use_count()==1 ;而 r 为空。等价于 shared_ptr<T>(r).swap(*this) 。

4) 转移 r 所管理对象的所有权给 *this 。为将来删除被管理对象,存储关联到 r 的删除器。调用后 r 不管理对象。等价于 shared_ptr<T>(std::move(r)).swap(*this) 。

参数

r-要获得所有权或共享所有权的另一智能指针

返回值

*this

注意

实现可以满足要求而无需创建临时的 shared_ptr 对象。

异常

3) (无)

4) 可能抛异常

替换所管理的对象

std::shared_ptr<T>::reset
void reset() noexcept;    (1) (C++11 起) 

template< class Y >void reset( Y* ptr ); (2) (C++11 起) 

template< class Y, class Deleter >void reset( Y* ptr, Deleter d );(3) (C++11 起) 

template< class Y, class Deleter, class Alloc >
void reset( Y* ptr, Deleter d, Alloc alloc ); (4) (C++11 起) 

ptr 所指向的对象替换被管理对象。能可选地提供删除器 d ,之后在无 shared_ptr 对象占有该对象是以之销毁新对象。默认以 delete 表达式为删除器。始终选择对应提供类型的 delete 表达式,这是函数以使用分离的形参 Y 的模板实现的理由。

*this 已占有对象,且它是最后一个占有该对象的 shared_ptr ,则通过所占有的删除器销毁对象。

ptr 所指向的对象已被占有,则函数导致未定义行为。

1) 释放被管理对象的所有权,若存在。调用后, *this 不管理对象。等价于 shared_ptr().swap(*this); 。

2-4) 以 ptr 所指向对象替换被管理对象。 Y 必须是完整类型且可隐式转换为 T 。另外:

2) 以 delete 表达式为删除器。合法的 delete 表达式必须可用,即 delete ptr 必须为良式,拥有良好定义行为且不抛任何异常。等价于 shared_ptr<T>(ptr).swap(*this); 。

3) 以指定的删除器 d 为删除器。 Deleter 必须对 T 类型可调用,即 d(ptr)必须为良式,拥有良好定义行为且不抛任何异常。 Deleter 必须可复制构造 (CopyConstructible) ,且其复制构造函数和析构函数必须不抛异常。等价于 shared_ptr<T>(ptr, d).swap(*this); 。

4) 同 (3) ,但额外地用 alloc 的副本分配内部使用的数据。 Alloc 必须是分配器 (Allocator) 。复制构造函数和析构函数必须不抛异常。等价于 shared_ptr<T>(ptr, d, alloc).swap(*this); 。

参数

ptr-指向要取得所有权的对象的指针
d-为删除对象而存储的删除器
alloc-内部存储所用的分配器

返回值

(无)

异常

2) 若无法获得要求的额外内存则为 std::bad_alloc 。可能因其他错误抛出实现定义的异常。若出现异常则调用 delete ptr 。

3-4) 若无法获得要求的额外内存则为 std::bad_alloc 。可能因其他错误抛出实现定义的异常。若出现异常则调用 d(ptr) 。

调用示例

#include <memory>
#include <iostream>

struct Foo
{
    Foo(int n = 0) noexcept : bar(n)
    {
        std::cout << "Foo: constructor, bar = " << bar << '\n';
    }
    ~Foo()
    {
        std::cout << "Foo: destructor, bar = " << bar << '\n';
    }
    int getBar() const noexcept
    {
        return bar;
    }
private:
    int bar;
};

int main()
{
    std::shared_ptr<Foo> sptr = std::make_shared<Foo>(1);
    std::cout << "The first Foo's bar is " << sptr->getBar() << "\n";

    // 重置,交与新的 Foo 实例
    // (此调用后将销毁旧实例)
    sptr.reset(new Foo);
    std::cout << "The second Foo's bar is " << sptr->getBar() << "\n";
}

输出

交换所管理的对象

std::shared_ptr<T>::swap
void swap( shared_ptr& r ) noexcept;  (C++11 起) 

交换 *this 与 r 的内容。

参数

r-要与之交换内容的智能指针

返回值

(无)

检查所管理对象是否仅由当前 shared_ptr 的实例管理

std::shared_ptr<T>::unique
bool unique() const noexcept;  (C++17 中弃用)  (C++20 中移除) 

检查 *this 是否管理当前对象的仅有 shared_ptr 实例,即是否 use_count() == 1 。

参数

(无)

返回值

若 *this 否管理当前对象的仅有 shared_ptr 实例则为 true ,否则为 false 。

注意

此函数于 C++17 中被弃用并于 C++20 中移除,因为 use_count 在多线程环境中只是估计(见 use_count 中的“注意”)。

调用示例

#include <memory>
#include <iostream>

int main()
{
    auto sp1 = std::make_shared<int>(5);
    std::cout << std::boolalpha;
    std::cout << "sp1.unique() == " << sp1.unique() << '\n';

    std::shared_ptr<int> sp2 = sp1;
    std::cout << "sp1.unique() == " << sp1.unique() << '\n';
    std::cout << "sp2.unique() == " << sp2.unique() << '\n';
}

 输出

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值