shared_ptr的基本用法
方法①:使用 std::make_shared(推荐!)

#include <memory>
#include <iostream>

class MyClass {
public:
    MyClass(int val) : value(val) {
        std::cout << "MyClass constructed: " << value << "\n";
    }
    ~MyClass() {
        std::cout << "MyClass destroyed: " << value << "\n";
    }
    void print() const { std::cout << "Value: " << value << "\n"; }

private:
    int value;
};

int main() {
    // 推荐方式:高效、异常安全
    auto ptr1 = std::make_shared<MyClass>(42);
    ptr1->print();  // Value: 42
}

方法②:直接构造(不推荐,除非必要)

std::shared_ptr<MyClass> ptr2(new MyClass(100));

❌ 不推荐用 reset(new T) 创建对象

std::shared_ptr<MyClass> p;
p.reset(new MyClass(42)); // 语法正确,但不推荐!

std::shared_ptr 的高级用法之一:使用 Lambda 表达式作为自定义删除器(custom deleter)。

我们先来看一段典型的 shared_ptr 使用代码:

#include <iostream>
#include <memory>
using namespace std;

class MyEngine {
public:
    MyEngine() { cout << "MyEngine created.\n"; }
    void infer() { cout << "Running inference...\n"; }
    void destroy() { cout << "MyEngine destroyed!\n"; delete this; }
};

int main() {
    MyEngine* ptr = new MyEngine();

    cout << "Step 1: Creating shared_ptr...\n";

    auto engine = shared_ptr<MyEngine>(ptr, [](MyEngine* p) {
        cout << ">>> Lambda is NOW running: ";
        p->destroy();
    });

    cout << "Step 2: shared_ptr created. Object is still alive.\n";

    // ✅ 调用 infer() —— 不会触发 lambda!
    engine->infer();

    cout << "Step 3: Leaving scope...\n";
    // 此时 engine 析构,才会触发 lambda 执行
}

结果:

MyEngine created.
Step 1: Creating shared_ptr...
Step 2: shared_ptr created. Object is still alive.
Running inference...
Step 3: Leaving scope...
>>> Lambda is NOW running: MyEngine destroyed!

🔍 核心问题:为什么 engine->infer() 没有执行 lambda?

这是本文的核心!我们来逐行分析。
✅ 1. shared_ptr 的构造:只保存,不执行
auto engine = shared_ptr(ptr, [](MyEngine* p) { … });

这行代码做了什么?

保存原始指针 ptr
保存 lambda 作为“删除器”(deleter)

👉 但 不会立即执行 lambda!

你可以把 lambda 理解为一张“遗嘱”:

“当我(engine)死的时候,请用这个函数清理我的遗体。”

管家(shared_ptr)收下了遗嘱,但不会立刻执行。
✅ 2. engine->infer():只是正常使用对象
engine->infer();

这行代码等价于:MyEngine* raw = engine.get();
raw->infer();
👉 它只是通过 shared_ptr 获取原始指针,然后调用方法。

完全不涉及删除器!
✅ 3. 析构时:删除器终于执行

当 main() 函数结束,engine 离开作用域,它的析构函数被调用:

这才是 lambda 第一次也是唯一一次被执行。

更多推荐