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

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

(0)头文件

#include

(1)如何初始化


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

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

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

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

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

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

 

(2)何时会释放资源

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

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

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

拷贝:auto sp2 = make_shared(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

 

你可能感兴趣的:(c++,智能指针,unique_ptr,shared_ptr,内存泄漏,引用计数)