Z
ZHANK
内存管理进阶

智能指针深入

make_unique/make_shared 优势、自定义删除器、enable_shared_from_this

智能指针深入

make_unique/make_shared 不仅是语法糖——它们更安全、更高效。自定义删除器让智能指针管理任何资源。

学完本章你将: 掌握 make 函数优势、自定义删除器、enable_shared_from_this。


make_unique / make_shared 为什么更好

cpp
// ❌ 两次内存分配(对象 + 控制块)
std::shared_ptr<int> sp1(new int(42));

// ✅ 单次分配(对象和控制块在一起)
auto sp2 = std::make_shared<int>(42);

// ❌ 异常不安全
process(std::shared_ptr<Foo>(new Foo), mayThrow());
// 如果 new Foo 成功,但 mayThrow 在 shared_ptr 构造前抛异常 → 泄漏

// ✅ 异常安全
process(std::make_shared<Foo>(), mayThrow());

自定义删除器

cpp
// 管理 FILE* —— 不只是内存
auto file_deleter = [](FILE* f) {
    if (f) {
        fclose(f);
        std::cout << "文件关闭\n";
    }
};

std::unique_ptr<FILE, decltype(file_deleter)>
    file(fopen("test.txt", "w"), file_deleter);

// shared_ptr 的自定义删除器更简洁
std::shared_ptr<FILE> file2(fopen("test.txt", "r"),
    [](FILE* f) { if (f) fclose(f); });

enable_shared_from_this

cpp
class Node : public std::enable_shared_from_this<Node> {
public:
    std::shared_ptr<Node> getPtr() {
        return shared_from_this();  // 安全地返回 this 的 shared_ptr
    }
};

auto node = std::make_shared<Node>();
auto ptr = node->getPtr();  // 和 node 共享同一引用计数

// ❌ 危险模式
// Node n;
// n.getPtr();  // bad_weak_ptr 异常——必须已经由 shared_ptr 管理