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

成员函数调用过程中销毁对象是否属于未定义行为?

成员函数执行期间销毁对象的行为判定

问题场景

  • 调用对象的成员函数(如mystruct.method())
  • 函数调用过程中触发对象销毁:例如对象由容器内的std::shared_ptr持有,调用的函数移除了最后一个维持对象存活的shared_ptr
  • 成员函数执行流程中,对象的析构函数被调用,对象生命周期结束

很多人会担心:成员函数执行过程中对象已不存在,但仍处于函数执行流程中,这种情况的行为是否明确?

测试示例

有如下测试代码:

struct mystruct {
    void mymethod() {
      std::cerr << "in mymethod, calling f()\n";
      f();
      std::cerr << "in my method, after f()\n";
    }

    std::function<void(void)> f;

    ~mystruct() { std::cerr << " ~~~ in mystruct dtor\n"; }
};

std::set<std::shared_ptr<mystruct>> set;

auto tmp = std::make_shared<mystruct>();
tmp->f = [&]() {
  set.clear();
  std::cerr << "in lambda\n";
};

auto &ref = *tmp;

set.insert(std::move(tmp));
ref.mymethod();

程序输出:

in mymethod, calling f()
 ~~~ in mystruct dtor
in lambda
in my method, after f()

行为判定

这个场景的行为是定义明确的,原因如下:

  1. 调用mymethod()时,对象处于存活状态,调用成员变量f的行为合法。
  2. 在lambda执行set.clear()时,最后一个shared_ptr被销毁,触发对象析构,此时对象生命周期结束。但lambda本身没有访问对象的任何非静态成员,只是操作外部的set并输出内容,这部分执行不受对象销毁的影响。
  3. 从lambda返回后,mymethod()剩余的代码只是执行字符串输出,没有访问对象的任何成员或调用其他非静态成员函数,也不会解引用this指针,因此这部分执行也是合法的。

需要注意的是,如果在对象销毁后,成员函数仍尝试访问对象的非静态成员(比如读取成员变量、调用其他成员函数),那么这种行为属于未定义行为,此时即使valgrind或 sanitizers 没检测出问题,也不能保证程序行为的稳定性。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.13 15:55:12