附录 | BUG踩坑----智能指针
指针和智能指针

在c/c++中有一个很重要的概念,管理内存地址,即手动为数据分配内存,从而诞生了指针这一概念。
指针是一个变量,其存储的是值的地址。

我们在声明了一个指针变量后,会在自由存储区为该变量开辟内存空间,以供后来使用。
指针的强大之处在于它可以自由的分配和管理内存,但也因此容易引发内存泄漏的问题。
所谓的内存泄露,指的是不再使用的内存空间,未被及时的释放和回收。
大约有以下几种内存泄露的情况:
为指针分配堆中的内存,但没有回收。即没有delete掉这个指针。

在回收指针前,程序因为其他原因提前结束。比如异常抛出的情况。

没有将基类的析构函数定义为虚函数。这种情况主要发生在声明了一个基类指向子类的指针被错误释放,而导致的内存泄露问题。
野指针:指向指向被释放的或者访问受限内存的指针。主要原因还是在于空指针没有被置为NULL。

为了有效、方便的避免这些问题,c++11后提出了新的智能指针 shared_ptr、unique_ptr和weak_ptr,这三种智能指针模板类来管理指针。
智能指针本质上是模板类,是对象,可以将new获得的地址赋给这种对象,当智能指针过期时,其析构函数将使用delete来释放内存。

注意,所有智能指针的构造函数均为 explicit构造函数,该关键字作用是取消隐式转换,并且只能有一个参数(如果其他参数有初始值也可以)。
也就是说,你不能用以下这种方式来赋值指针:


unique_ptr:
它对其所指向的对象拥有独享权,unique_ptr 不共享它所管理的对象。
多个指针无法指向同一个对象。
它无法通过直接赋值的方式来传递对象,只能通过引用的方式,或者通过 std::move(所有权转移)的方式来传递对象。传递完成后,原本的指针将变成空指针。
另一种情况,用函数返回一个 unique_ptr指针也是可以的,因为这个指针是临时指针,在使用完之后会被自动释放。但是这需要满足另一个指针也是 unique_ptr 才可以。

还有一种情况,在 unique_ptr 为右值时,可以将其赋值给 shared_ptr。这是因为 shared_ptr有一个显式构造函数。

shared_ptr:
shared_ptr 是一个标准的共享所有权的智能指针,允许多个指针指向同一个对象。
它含有计数功能,通过 shared_ptr.use_count() 可以得到当前对象被多少个指针共享。
当一个shared_ptr赋值给另一个shared_ptr时,被赋值的指针的原内存会被销毁,回收。