You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

何时及为何在unique_ptr中使用自定义删除器而非默认删除器?

何时使用unique_ptr的自定义删除器?

默认的unique_ptr删除器只会调用delete来释放内存,但实际开发里不是所有资源都能用这种方式处理,以下几种场景必须用自定义删除器:

适用场景

  • 非new分配的内存:如果内存是用malloc、calloc或者其他C风格分配函数拿到的,用默认delete释放会导致未定义行为,必须用对应释放函数(比如free)作为删除器。
  • 管理非内存资源:比如文件句柄、数据库连接、网络套接字这类资源,它们的释放依赖专门的API(比如fclose、close),而非delete。
  • 需要额外销毁逻辑:销毁对象前要打日志、释放关联的附属资源、通知其他模块状态变化等,默认删除器做不到这些扩展操作。

简单示例

1. 释放malloc分配的内存

#include <memory>
#include <cstdlib>
#include <iostream>

int main() {
    // 用C风格malloc分配内存
    int* raw_ptr = static_cast<int*>(std::malloc(sizeof(int)));
    *raw_ptr = 42;

    // 自定义删除器:调用free释放内存,同时加日志
    std::unique_ptr<int, void(*)(int*)> u_ptr(raw_ptr, [](int* p) {
        std::cout << "释放malloc分配的内存\n";
        std::free(p);
    });
}

如果这里用默认unique_ptr,离开作用域时会调用delete,但malloc和delete不配对,会触发未定义行为,自定义删除器解决了这个问题。

2. 自动关闭文件句柄

#include <memory>
#include <cstdio>

int main() {
    FILE* file = std::fopen("test.txt", "r");
    if (!file) return 1;

    // 用fclose作为自定义删除器,自动关闭文件
    std::unique_ptr<FILE, int(*)(FILE*)> file_ptr(file, std::fclose);

    // 这里可以安全操作文件,无需手动调用fclose
    // 离开作用域时,unique_ptr会自动调用fclose关闭文件
}

FILE*不是通过new创建的,默认删除器的delete完全不适用,自定义删除器确保资源被正确释放,避免文件句柄泄漏。

3. 带额外逻辑的对象销毁

#include <memory>
#include <iostream>

class NetworkConnection {
public:
    NetworkConnection() { std::cout << "建立网络连接\n"; }
    void sendData() { /* 发送数据逻辑 */ }
};

int main() {
    NetworkConnection* conn = new NetworkConnection();
    // 自定义删除器:销毁前打印断开日志,再调用delete
    std::unique_ptr<NetworkConnection> conn_ptr(conn, [](NetworkConnection* p) {
        std::cout << "断开网络连接\n";
        delete p;
    });
}

这里虽然最终还是调用delete,但在销毁前执行了额外的日志操作,方便排查问题,这是默认删除器无法实现的。

内容的提问来源于stack exchange,提问作者Mangy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.03 14:35:23