shared_ptr 与 Lambda 删除器
·
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 第一次也是唯一一次被执行。
更多推荐


所有评论(0)