如果从构造函数/析构函数无条件调用虚函数,是否会发生虚调度? [英] If a virtual function is called from a constructor/destructor without qualification, does virtual dispatch occur?

查看:85
本文介绍了如果从构造函数/析构函数无条件调用虚函数,是否会发生虚调度?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

struct A
{
    virtual ~A() { f(); }

    virtual void f() {}
};

我已对问题进行了更具体的编辑。.

I've edited my question to be more specific..

在此代码示例中,调用 f()可以使用虚拟调度,还是可以保证等效于 A :: f ()

In this code sample, MAY the call f() use virtual dispatch, or is it guaranteed equivalent to A::f()?

能否提供C ++标准的相关部分?谢谢。

Could you provide relevant section from C++ standard? Thanks.

推荐答案

在构造函数或析构函数内,子类对象尚未构造或已被破坏。 。结果,虚拟调度不会导致使用派生类版本,而是会调用基类版本。

Within a constructor or destructor, the sub-class object has either not yet been constructed, or has already been destroyed. As a result, virtual dispatch does not lead to the derived-class version being used, and instead the base-class version is called.

根据标准, [class.cdtor] / 4


成员函数,包括虚拟函数(10.3),可以在构造或销毁期间调用(12.6.2)。当从构造函数或析构函数直接或间接调用虚拟函数时,包括在构造或破坏类的非静态数据成员的过程中,并且调用所应用的对象是正在构造的对象(称为x)或销毁,所调用的函数是构造函数或析构函数的类中的最终重写器,而不是在派生更高的类中对其进行重写的函数。如果虚拟函数调用使用显式类成员访问(5.2.5),并且对象表达式引用x的完整对象或该对象的基类子对象之一,而不引用x或其基类子对象之一,则该行为未定义

Member functions, including virtual functions (10.3), can be called during construction or destruction (12.6.2). When a virtual function is called directly or indirectly from a constructor or from a destructor, including during the construction or destruction of the class’s non-static data members, and the object to which the call applies is the object (call it x) under construction or destruction, the function called is the final overrider in the constructor’s or destructor’s class and not the one overriding it in a more-derived class. If the virtual function call uses an explicit class member access (5.2.5) and the object expression refers to the complete object of x or one of that object’s base class subobjects but not x or one of its base class subobjects, the behavior is undefined.

举一个例子:

struct V {
   virtual void f();
   virtual void g();
};
struct A : virtual V {
   virtual void f();
};
struct B : virtual V {
   virtual void g();
   B(V*, A*);
};
struct D : A, B {
   virtual void f();
   virtual void g();
   D() : B((A*)this, this) { }
};
B::B(V* v, A* a) {
    f(); // calls V::f, not A::f
    g(); // calls B::g, not D::g
    v->g(); // v is base of B, the call is well-defined, calls B::g
    a->f(); // undefined behavior, a’s type not a base of B
}

如果调用的函数是纯虚拟的,则从 [class.abstract] / 6

Also note that this can be unsafe if the function that is called is pure virtual, from [class.abstract]/6:


成员函数可以从抽象类的构造函数(或析构函数)中调用;对于从这样的构造函数(或析构函数)创建(或销毁)的对象直接或间接对纯虚拟函数进行虚拟调用(10.3)的效​​果是不确定的。

Member functions can be called from a constructor (or destructor) of an abstract class; the effect of making a virtual call (10.3) to a pure virtual function directly or indirectly for the object being created (or destroyed) from such a constructor (or destructor) is undefined.

这篇关于如果从构造函数/析构函数无条件调用虚函数,是否会发生虚调度?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆