【问题标题】:What type for virtual function does a class have when a member destructor runs?当成员析构函数运行时,类的虚函数类型是什么?
【发布时间】:2016-08-19 00:47:56
【问题描述】:

我有这种情况:

#include <iostream>

struct B { virtual void f() { std::cout << "base"; } };

struct A {
  ~A() {
      b->f();
  }

  B *b;
};


struct Bd : B { 
  Bd():a{this}{ }
  ~Bd() { }
  virtual void f() { std::cout << "derived"; } 

  A a;
};

int main() {
  Bd d;
}

是否保证这会打印“派生”?

【问题讨论】:

  • 我认为它要么调用B::f,要么调用未定义的行为。对象的生命周期正式结束when its destructors begins,所以当A::~A 调用b-&gt;f(); 时,b 的派生部分已经死亡。
  • 也看看this
  • @Quentin 那句话看起来根本不对。您绝对可以从其自己的析构函数中访问对象,这与禁止在其生命周期结束后访问它的规定不一致。

标签: c++ virtual


【解决方案1】:

[class.cdtor]/4:

成员函数,包括虚函数([class.virtual]),可以 在构造或销毁期间调用([class.base.init])。什么时候 从构造函数直接或间接调用虚函数 或来自析构函数,包括在构造或销毁期间 类的非静态数据成员,和对象 call apply 是正在构建的对象(称为x)或 销毁,调用的函数是最终的覆盖 构造函数或析构函数的类,而不是在 更多派生类。

这里的“类”是Bd,所以它应该在Bd中调用f()的最终覆盖,并打印derived

【讨论】:

    【解决方案2】:

    我现在没时间查,但规则是,对正在运行析构函数的对象的虚拟调用会转到当前正在运行析构函数的类。所以在Bd 的析构函数中,a 的析构函数运行,b-&gt;f() 调用调用Bd::f

    如果aB 的成员而不是Bd,则调用将转到B::f,因为a 的析构函数将从B 的析构函数运行。

    如果您更喜欢考虑机制(我通常不喜欢),请考虑 vtable;在进入析构函数时,代码将 vtable 指针设置为指向属于正在运行的析构函数的 vtable。

    【讨论】:

      猜你喜欢
      • 2021-06-25
      • 2019-03-15
      • 1970-01-01
      • 1970-01-01
      • 2012-06-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多