std::shared_ptr<T>::reset

来自cppreference.com
< cpp‎ | memory‎ | shared ptr
 
 
内存管理库
(仅用于阐述*)
分配器
未初始化内存算法
受约束的未初始化内存算法
内存资源
未初始化存储(C++20 前)
(C++17 弃用)
(C++17 弃用)
垃圾收集器支持(C++23 前)
(C++11)(C++23 前)
(C++11)(C++23 前)
(C++11)(C++23 前)
(C++11)(C++23 前)
(C++11)(C++23 前)
(C++11)(C++23 前)
 
 
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 <iostream>#include <memory>   struct Foo { Foo(int n =0)noexcept: bar(n){std::cout<<"Foo::Foo(), bar = "<< bar <<" @ "<< this <<'\n';} ~Foo(){std::cout<<"Foo::~Foo(), bar = "<< bar <<" @ "<< this <<'\n';}int getBar()constnoexcept{return bar;}private:int bar;};   int main(){std::cout<<"1) 独占所有权\n";{std::shared_ptr<Foo> sptr =std::make_shared<Foo>(100);   std::cout<<"Foo::bar = "<< sptr->getBar()<<", use_count() = "<< sptr.use_count()<<'\n';   // 重置 shared_ptr 而不给它新的 Foo 实例。// 此调用后原实例将被销毁。std::cout<<"调用 sptr.reset()...\n"; sptr.reset();// 此处调用 Foo 的析构函数std::cout<<"调用 reset() 后: use_count() = "<< sptr.use_count()<<", sptr = "<< sptr <<'\n';}// 不调用 Foo 的析构函数,已在早前的 reset() 中调用   std::cout<<"\n2) 独占所有权\n";{std::shared_ptr<Foo> sptr =std::make_shared<Foo>(200);   std::cout<<"Foo::bar = "<< sptr->getBar()<<", use_count() = "<< sptr.use_count()<<'\n';   // 重置 shared_ptr,传给它 Foo 的新实例。// 此调用后原实例将被销毁。std::cout<<"调用 sptr.reset()...\n"; sptr.reset(new Foo{222});std::cout<<"调用 reset() 后: use_count() = "<< sptr.use_count()<<", sptr = "<< sptr <<"\n离开作用域...\n";}// 调用 Foo 的析构函数。   std::cout<<"\n3) 多重所有权\n";{std::shared_ptr<Foo> sptr1 =std::make_shared<Foo>(300);std::shared_ptr<Foo> sptr2 = sptr1;std::shared_ptr<Foo> sptr3 = sptr2;   std::cout<<"Foo::bar = "<< sptr1->getBar()<<", use_count() = "<< sptr1.use_count()<<'\n';   // 重置 shared_ptr sptr1,传给它 Foo 的新实例。// 原实例仍在 sptr2 和 sptr3 之间共享。std::cout<<"调用 sptr1.reset()...\n"; sptr1.reset(new Foo{333});   std::cout<<"调用 reset() 后:\n"<<"sptr1.use_count() = "<< sptr1.use_count()<<", sptr1 @ "<< sptr1 <<'\n'<<"sptr2.use_count() = "<< sptr2.use_count()<<", sptr2 @ "<< sptr2 <<'\n'<<"sptr3.use_count() = "<< sptr3.use_count()<<", sptr3 @ "<< sptr3 <<'\n'<<"离开作用域...\n";}// 调用两个析构函数: 1) sptr1 所拥有的 Foo,// 2) sptr2/sptr3 所共享的 Foo。}

可能的输出:

1) 独占所有权 Foo::Foo(), bar = 100 @ 0x23c5040 Foo::bar = 100, use_count() = 1 调用 sptr.reset()... Foo::~Foo(), bar = 100 @ 0x23c5040 调用 reset() 后: use_count() = 0, sptr = 0   2) 独占所有权 Foo::Foo(), bar = 200 @ 0x23c5040 Foo::bar = 200, use_count() = 1 调用 sptr.reset()... Foo::Foo(), bar = 222 @ 0x23c5050 Foo::~Foo(), bar = 200 @ 0x23c5040 调用 reset() 后: use_count() = 1, sptr = 0x23c5050 离开作用域... Foo::~Foo(), bar = 222 @ 0x23c5050   3) 多重所有权 Foo::Foo(), bar = 300 @ 0x23c5080 Foo::bar = 300, use_count() = 3 调用 sptr1.reset()... Foo::Foo(), bar = 333 @ 0x23c5050 调用 reset() 后: sptr1.use_count() = 1, sptr1 @ 0x23c5050 sptr2.use_count() = 2, sptr2 @ 0x23c5080 sptr3.use_count() = 2, sptr3 @ 0x23c5080 离开作用域... Foo::~Foo(), bar = 300 @ 0x23c5080 Foo::~Foo(), bar = 333 @ 0x23c5050

[编辑]参阅

构造新的 shared_ptr
(公开成员函数)[编辑]
close