1. 引用和指针的取舍

引用和指针是什么无需赘述。要解决实际应用时如何在二者中进行取舍,主要关注可空性和可重定向性这两个特性。

  1. 可空性
    在CPP11引入nullptr以后,空指针就有了唯一的指代值。
    使用指针时,可以使该指针指向某个特定的地址,或者为nullptr,而使用引用,则在创建该引用时就必须指定明确的引用目标。

  2. 可重定向性
    指针指向的地址可以任意修改,而引用则无法修改。

2. 访问堆上变量

堆上的数据都是匿名的,所以如果想访问堆上数据,起点一定在其他的内存分配区域。
一般有三种形式来开辟堆上内存区域:直接调用new关键字,构造自定义或标准容器类,调用智能指针工厂函数。
(后两种底层上也调用了new关键字,但它们支持RAII自动析构,不用手动delete。)

3. 是否取用智能指针

引入智能指针的目的是为了自动管理堆上变量的生命周期,也就是说,当你需要使变量获得与函数作用域解绑的生命周期时,则引入智能指针。

4. 借用机制

如果程序承诺:观察者的生命周期永远被包含在所有者以内,那么所有者可以向观察者借出数据。
表现为,在观察者的程序流中尝试用裸指针获取智能指针中的内容。
auto *table_heap = table->table_.get();
如果无法完成承诺,那么智能指针可能在最后一次调用裸指针之前析构,销毁该地址上的所有内容,再调用裸指针时就会引发悬垂指针的问题,产生非法访问。
(显然,智能指针的数据结构无法得知除了其本身(或其他shared_ptr)以外是否仍有变量持有此数据,即,裸指针对该智能指针不可见)