C++疑点难点

来自 UP：HexUp
《30 分钟讲明白现代 C++ 最重要的特性之一：智能指针》

类型声明

遵循 “右左” 法则
从变量名开始向右看 看完后向左看
不可忽略括号 即一层层括号地看
跳出一层后的外层表示的是内层元素的类型或者内层指针的指向
读取过程的顺序表示后者是前者元素的类型
const一类的声明也遵从 “右左” 法则

指针大小

32 位（Bit）架构和 64 位（Bit）架构
内存的最小单位 1 字节（Byte）=8 Bit
32Bit 程序的指针大小 4 字节
64Bit 程序的指针大小 8 字节
指针大小在本质上由编译器决定

Lambda 表达式

又名闭包
结构：
[ 捕获变量 ]( 参数列表 ) -> 返回类型 { 函数主体 }
变量捕获时不加&按值捕获，加&按引用捕获
[&]按引用捕获所有外部变量
[=]按值捕获所有外部变量
上述二者可以结合，[&,=N]除了变量N按值捕获外其他外部变量全部按引用捕获

裸指针与动态内存分配

new用来动态申请内存
delete用来手动释放动态申请的内存，否则这部分内存不会被释放，如果new申请的空间为数组，需要使用delete[]
智能指针用来避免手动管理内存可能导致的内存泄漏

shared_ptr

需要#include <memory>，属于std命名空间
初始化：
shared_ptr<int> p {make_shared<int>(100)};
shared_ptr<int> p {new int(100)};
shared_ptr<int> p = make_shared<int>(100);
上述几种方式完全等价
p.use_count()有多少个指针指向同一 object
p.reset()重置指针，不再指向原 object；也可以设置参数使其指向新的 object
当指向某一 object 的shared_ptr降为 0，这一 object 会自动销毁
p.get()获取指向当前 object 的裸指针
初始化还有一些特殊的参数配置如下：
shared_ptr<FILE> sfp {fp, close_file}; 第二个参数为自定义的销毁函数
shared_ptr<Bar> b(f, &(f->b)); 第二个参数用于访问类的成员变量

unique_ptr

库基础、初始化方式与shared_ptr相同
独占 object 的管理权，销毁时自动释放所绑定的 object
p.release()会返回 object 的裸指针同时设置 p 为nullptr
控制权不可拷贝但可转移
unique_ptr<int> p2 {p1.release()}
unique_ptr<int> p2 {move(p1)}
将 p1 的控制权转移给 p2，上述两式等价
unique_ptr<int, decltype(&my_dealloc)> cup {my_alloc(100), my_dealloc} 自定义销毁函数更加复杂，需要在<>内声明
函数间传递时可以使用*p直接传递值，也可以使用p.get()传递裸指针，或者将函数的参数设置为unique_ptr<int>&即unique_ptr的引用，还可以使用move(p)来改变 object 的控制权（此时函数的参数为unique_ptr<int>）
函数的返回值没有额外的限制，可以直接使用unique_ptr<int>类型的函数返回值初始化unique_ptr<int>，其本质也是调用move

weak_ptr

可以解决环形依赖问题
weak_ptr依赖shared_ptr存在，需要用shared_ptr初始化
weak_ptr只有 object 的观察权，没有 object 的管理权
wp.lock()会返回一个shared_ptr，若weak_ptr所指向的资源已释放，则返回nullptr