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

如何为自定义函数创建std::shared_ptr类型的智能指针?

给函数指针创建智能指针的正确姿势

嘿,先给你掰明白一个核心点:std::shared_ptr这类智能指针本来是用来管理动态分配的内存(比如new出来的对象)的,而函数本身存在程序的代码段里,根本不需要我们手动释放内存,所以其实大部分场景下,完全没必要用智能指针去管理函数指针。不过如果你确实有特殊需求(比如要把函数指针塞进要求智能指针的容器里),那咱们可以这么搞:

1. 直接用shared_ptr管理函数指针(必须自定义删除器!)

默认的shared_ptr会在最后调用delete去释放指针,但函数指针可不能被delete,一删就崩了!所以必须给它配个啥也不干的删除器:

#include <memory>

double returnValue(int i){ return i; }

int main() {
    // 先给函数指针整个别名,写起来方便
    using FuncPtr = double(*)(int);
    
    // 创建shared_ptr,第二个参数就是空删除器——啥也不做
    std::shared_ptr<void> func_ptr(&returnValue, [](void*) {});
    
    // 要调用的话,得把void*转回到原来的函数指针类型
    auto call_func = static_cast<FuncPtr>(func_ptr.get());
    double res = call_func(5); // 这里会得到5.0
    return 0;
}

这里用std::shared_ptr<void>是因为函数指针类型没法直接当shared_ptr的模板参数(shared_ptr默认要求模板类型是可被delete的,函数指针不符合),所以转成void*绕一下,再靠自定义删除器避免错误操作。

2. 封装成可调用对象(更优雅的玩法)

如果只是想要类似智能指针的共享语义,不如把函数包成一个无状态的可调用对象,再用shared_ptr管这个对象,这更符合智能指针的设计初衷:

#include <memory>

double returnValue(int i){ return i; }

// 把函数包进一个结构体里,重载()运算符
struct FuncWrapper {
    double operator()(int i) const {
        return returnValue(i);
    }
};

int main() {
    // 直接make_shared创建这个封装对象
    auto func_ptr = std::make_shared<FuncWrapper>();
    double res = (*func_ptr)(5); // 直接调用就行
    return 0;
}

为啥你之前的尝试失败了?

你用auto someptr = std::make_shared<double>(&returnValue);的时候,std::make_shared<double>是用来创建一个double类型的对象,并用你传的参数去初始化它——但你传的是函数指针,这就会把函数指针的地址强行转成double值,完全不是你要的“管理函数指针”的效果,当然会失败啦。

最后总结下:如果不是非用不可,直接用原始函数指针就够了;真要上智能指针,要么自定义删除器,要么封装成可调用对象~

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 08:35:45