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

持有C++对象成员函数的shared_ptr时,对象析构函数是否会被调用?

问题解答

首先明确:objectA的析构函数是否被调用,完全取决于MyClass::getFuncPointer()内部如何构造并返回std::function<void()>,分两种核心场景分析:

场景1:析构函数不会被调用

如果getFuncPointer()内部通过std::enable_shared_from_this获取自身的shared_ptr,并将其捕获到std::function中,比如实现如下:

class MyClass : public std::enable_shared_from_this<MyClass> {
public:
    void func() {}
    std::shared_ptr<std::function<void()>> getFuncPointer() {
        auto self = shared_from_this();
        return std::make_shared<std::function<void()>>([self]() { self->func(); });
    }
};

此时std::function内部持有了objectA的shared_ptr,当objectB保存这个返回值后,objectA的引用计数会从1(仅objectB持有)变为2(objectB+std::function内部的self)。

当objectB调用objectA.reset()后,objectA的引用计数降为1,并未归零,因此析构函数不会被调用。这种情况下不存在“对象已销毁但函数还在执行”的问题,因为std::function持有的shared_ptr会保证对象存活到std::function本身被销毁为止。

场景2:析构函数会被调用

如果getFuncPointer()只是简单绑定成员函数的原始指针,没有捕获objectA的shared_ptr,比如实现如下:

std::shared_ptr<std::function<void()>> MyClass::getFuncPointer() {
    return std::make_shared<std::function<void()>>(std::bind(&MyClass::func, this));
}

这里std::bind仅捕获了原始指针this,并未持有objectA的shared_ptr。此时objectA的引用计数仅由objectB的shared_ptr维护,当objectB调用reset()后,引用计数归零,析构函数会立即被调用。

如果此时其他线程通过保存的std::function调用func(),就会访问已经被销毁的对象成员,这属于未定义行为——程序可能崩溃、出现乱码数据,或者表现出其他不可预测的结果,绝对要避免这种情况。

对两种疑问的回应

  • 你担心的“对象析构后函数仍在执行”的问题,只会出现在第二种场景中,本质是因为std::function没有持有对象的智能指针,无法保证对象生命周期;
  • 你疑惑的“函数指针如何让对象存活”,实际并非函数指针本身,而是std::function内部捕获的shared_ptr延长了对象的生命周期,这是符合智能指针设计逻辑的。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.27 19:13:35