定义于头文件 <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';
}