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

在构造函数中调度含虚函数的回调是否符合C++标准?

关于C++构造函数中调度虚函数回调的可靠性与标准合规性问题

正如Scott Meyers在《Effective C++(第3版)》中指出:

条款9:绝不在构造或析构过程中调用虚函数。

请参考以下C++代码:

class my_class
{

  my_class()
  {
    // here we _cannot_ call other_virtual()

    // but will this lambda call the correct function
    // if it is called after this CTOR has exited its scope?
    schedule_work([this]{ other_virtual(); });
  }

  void schedule_work(std::function<void()> callback);
  virtual void other_virtual() = 0;
};

class derived : public my_class
{
  derived() : my_class() {}
  
  // make sure to implement the pure virtual
  void other_virtual() override;
};

请问上述代码写法是否属于可靠的C实现?是否符合C标准的相关规定?


结论

这段代码是可靠且符合C++标准的,核心原因如下:

  • 构造函数中并未直接调用虚函数other_virtual(),只是将捕获this的lambda作为回调注册到schedule_work中,而该回调的执行时机是在my_class和derived的构造函数都完全执行完毕之后。
  • 当回调真正执行时,对象已完成完整构造,此时this指向的derived对象虚函数表已正确初始化,调用other_virtual()会正常触发derived中的重写版本,完全符合虚函数调用规则。

Scott Meyers的条款9禁止的是在构造/析构过程中直接或间接调用虚函数——因为此时子类部分尚未构造(或已析构),虚函数会被解析为当前正在构造/析构的基类版本(纯虚函数会直接导致未定义行为)。但本案例中虚函数调用发生在构造完成后,完全避开了该风险。

需要注意的额外事项:

  • 必须确保回调执行时,this指向的对象仍然存活,否则会触发悬空指针的未定义行为。
  • schedule_work需要保证回调不会在对象构造完成前被执行,否则仍会违反条款9的禁忌。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.05 01:33:19