接着上篇智能指针 unique_ptr
shared_ptr 共享资源指针
- 指针之间共享所有权,通过引用计数管理内存
- 最后一个指针被析构时,引用计数-1,等于0
初始化
- 裸指针初始化
std::shared_ptr<int> ptr(new int(1));
- make_shared
std::shared_ptr<int> ptr = std::make_shared<int>(1);
注:不支持隐式转换
cpp std::shared_ptr<int> ptr = new int(1); // 报错,不存在从int* 到std::shared_ptr<int>的转换
成员函数
- use_count()
获取当前引用计数 - unique()
是否该智能指针独占某个指向的对象,也就是若只有一个智能指针指向某个对象,则unique()返回true,多个返回fasle。 - reset()
- 无参时,调用该函数的shared_ptr对象的引用计数为0,而该片内存并不为0,只是减1
- 有参时,调用该函数的shared_ptr对象指向新的内存,引用计数加1。而原本的内存减1
//shared_ptr的比较 与 reset函数方法 void test(){ shared_ptr<int> ptr1=make_shared<int>(3); std::cout << ptr1.use_count() << std::endl; // count=1 shared_ptr<int> ptr3=ptr1; std::cout << ptr1.use_count() << std::endl; // count=2 //2.1 无参reset函数 使调用的shared_ptr指向一个空资源 只是该shared_ptr的引用计数变为0 其他的因为sh1调用reset而减1 ptr1.reset(); // 使sh1指向的count为0 std::cout << ptr1.use_count() << std::endl; // count=0 if (ptr1 == nullptr){ std::cout << "ptr1被置空" << std::endl; } std::cout << ptr3.use_count() << std::endl; // count=1 //2.2 有参reset 使shared_ptr指向参数new出的资源对象 ptr1.reset(new int(5)); // sh1指向该参数new出的资源 std::cout << ptr1.use_count() << std::endl; // count = 1 std::cout << ptr3.use_count() << std::endl; // count = 1 }
- get()
同unique_ptr - swap()
同unique_ptr
shared_ptr转unique_ptr
不可以转换
错误e.g.
std::shared_ptr<int> sharedPtr = std::make_shared<int>(3);
std::unique_ptr<int> ptr(sharedPtr.get());
std::cout << sharedPtr.use_count(); // 1
// 执行并没有错误,但是释放的时候会报错
经验之谈
- 不要用一个原始指针初始化多个shared_ptr,例如下面错误范例
int *ptr = new int;
shared_ptr<int> p1(ptr);
shared_ptr<int> p2(ptr); // 逻辑错误