// ===== CodeLab: C++ 智能指针 =====
// 来源: https://aoerliang.dpdns.org/articles/cpp-smart-pointers
// 以下代码片段按文章出现顺序拼接, 共 4 段

// ----- 片段 1 (cpp) -----
#include <memory>
using namespace std;

unique_ptr<int> p = make_unique<int>(42);   // C++14 推荐写法
cout << *p;                                 // 像指针一样用

// unique_ptr<int> q = p;                   // 编译错误:禁止拷贝
unique_ptr<int> q = move(p);                // 转移所有权,p 变空
if (!p) { /* p 现在是 nullptr */ }

// 放进容器
vector<unique_ptr<Widget>> widgets;
widgets.push_back(make_unique<Widget>());

// ----- 片段 2 (cpp) -----
shared_ptr<int> a = make_shared<int>(10);
{
    shared_ptr<int> b = a;   // 引用计数 2
    *b = 99;
}                            // b 销毁,计数回到 1
// a 销毁时计数归零,内存被释放

long n = a.use_count();      // 当前共享者数量
int* raw = a.get();          // 拿裸指针(仅观察,别 delete)

// ----- 片段 3 (cpp) -----
class Node {
    shared_ptr<Node> next;
    weak_ptr<Node> prev;   // 弱引用,防止循环
};

weak_ptr<int> w = a;               // 从 shared_ptr 构造
if (auto sp = w.lock()) {          // lock() 提升为 shared_ptr
    // 对象还活着,安全使用 sp
} else {
    // 对象已被释放
}

// ----- 片段 4 (cpp) -----
// 用 make 系列,别直接 new
auto p = make_unique<Widget>(args);

// 接口里用裸指针表示"借用",不转移所有权
void draw(Widget* w);            // 只借用

// 返回新对象时返回 unique_ptr,调用方决定如何持有
unique_ptr<Widget> loadWidget();
