#include <iostream>
#include <memory>

struct Node {
    explicit Node(const char* name) : name(name) { std::cout << name << " created" << std::endl; }
    ~Node() { std::cout << name << " destroyed" << std::endl; }
    const char* name;
    std::shared_ptr<Node> next;  // 强引用
    std::weak_ptr<Node> prev;    // 弱引用：不增加计数
};

int main() {
    std::cout << "--- shared_ptr 计数 ---" << std::endl;
    {
        auto a = std::make_shared<Node>("A");
        std::cout << "use_count = " << a.use_count() << std::endl;
        {
            auto b = a;  // 拷贝：计数 +1
            std::cout << "use_count = " << a.use_count() << std::endl;
        }  // b 析构：计数 -1
        std::cout << "use_count = " << a.use_count() << std::endl;
    }  // a 析构：计数变成 0，对象被销毁

    std::cout << "--- 循环引用：两个 shared_ptr 互相指着 ---" << std::endl;
    {
        auto x = std::make_shared<Node>("X");
        auto y = std::make_shared<Node>("Y");
        x->next = y;
        y->next = x;  // 循环了
    }  // 看输出：X 和 Y 都没有被销毁，内存泄漏
    std::cout << "--- 用 weak_ptr 打破循环 ---" << std::endl;
    {
        auto p = std::make_shared<Node>("P");
        auto q = std::make_shared<Node>("Q");
        p->next = q;
        q->prev = p;  // 反向用 weak_ptr
        if (auto locked = q->prev.lock()) {  // 使用前先 lock，拿到一个临时的 shared_ptr
            std::cout << "Q's prev is " << locked->name << std::endl;
        }
    }
    std::cout << "--- end of main ---" << std::endl;
    return 0;
}
