C++11 - std::shared_ptr和std::unique_ptr

c++的内存管理用惯了new和delete手动管理,但是有些场景这种手动管理的方式使用起来很不方便。然后想搞清楚智能指针的用法,常见问题如下:

(0)头文件

#include<memory>

(1)如何初始化


shared_ptr<string> p1 = make_shared<string>(10, '9');  
 
shared_ptr<string> p2 = make_shared<string>("hello");  
 
shared_ptr<string> p3 = make_shared<string>(); 

std::unique_ptr<int> up;//可以指向int的unique_ptr,不过是空的
up = std::unique_ptr<int>(new int(12));

//unique_ptr<T>
std::unique_ptr<string> up1(new string("bianchengzhuji"));
std::unique_ptr<int[]> up2(new int[10]);//数组需要特别注意

std::unique_ptr<int> up;//声明空的unique_ptr
int *p= new int(1111);
up.reset(p);//令up指向新的对象,p为内置指针

什么情况需要指定删除器?

如果对象不是new分配的,请传递删除器。

(2)何时会释放资源

当引用计数为0时,shared_ptr所管理的对象自动销毁。

那么哪些情况会影响引用计数呢?

赋值:auto sp = make_shared<int>(1024);//sp的引用计数为1

拷贝:auto sp2 = make_shared<int>(1024); auto sp1(sp2); 容易忽略的就是函数参数拷贝,传值方式会增加引用计数,引用方式则不会增加引用计数。

reset:调用reset会减少计数,sp.reset(),而如果sp是唯一指向该对象的,则该对象被销毁。

(3)二者的区别

首先最明显的区别自然是它们一个是专享对象,一个是共享对象。而正是由于共享,包括要维护引用计数等,它带来的开销相比于unique_ptr来说要大。另外,shared_ptr无法直接处理数组,因为它使用delete来销毁对象,而对于数组,需要用delete[]。因此,需要指定删除器。

相比于shared_ptr,unique_ptr的开销更小,甚至可以说和裸指针相当,它不需要维护引用计数的原子操作等等。

所以说,如果有可能,优先选用unique_ptr。

(4)有哪些禁忌用法

虽然shared_ptr能很大程度避免内存泄漏,但是使用不当,仍然可能导致意外发生。

存放于容器中的shared_ptr

不要使用多个裸指针初始化多个shared_ptr

猜你喜欢

转载自blog.csdn.net/Fan0920/article/details/108649488