如果有主体,在抽象构造函数/析构函数中调用纯虚函数是否安全? [英] Is it safe to call a pure virtual function in an abstract constructor/destructor, IF it has a body?

查看:39
本文介绍了如果有主体,在抽象构造函数/析构函数中调用纯虚函数是否安全?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

没有标记为BODY的行,我知道这是不安全的.但是有了它,这安全吗?

Without the line marked BODY, I know this is not safe. But with it, is this safe?

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

    virtual void f() = 0;
};

void A::f() {} // BODY

struct B : A
{
    void f() {}
};

int main()
{
    delete new B;
}

工作示例: http://ideone.com/9bRZ3i

推荐答案

如果要绕过虚拟调度并调用已定义的函数体,则必须限定函数名称:

If you want to bypass virtual dispatch and call the function body you have defined, you must qualify the function name:

virtual ~A() { A::f(); } // OK.

否则,该调用将启动虚拟调度,但仅向基类发起虚拟调度,因为派生类型的对象已在其基类之前被销毁.

Otherwise, the call will initiate virtual dispatch, but only to the base class, because the object of derived type has already been destroyed before its bases.

C ++ 11§12.7/4直接解决您的问题:

C++11 §12.7/4 directly addresses your question:

成员函数,包括虚拟函数(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 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.

但是,§10.4/6禁止使用纯虚函数执行此操作:

However, §10.4/6 forbids doing this with a pure virtual function:

可以从抽象类的构造函数(或析构函数)中调用成员函数;对于从这样的构造函数(或析构函数)创建(或销毁)的对象直接或间接地对纯虚函数进行虚拟调用(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.

所以,它是UB.

纯虚拟"的作用是从虚拟查找中隐藏函数定义.除了可能是由于未定义行为的影响之外,您将永远不会从动态调度函数调用中获得纯虚拟函数的定义.

The effect of "pure virtual" is to hide the function definition from virtual lookup. You will never reach the definition of a pure virtual function from a dynamic dispatch function call, except perhaps as an effect of undefined behavior.

这篇关于如果有主体,在抽象构造函数/析构函数中调用纯虚函数是否安全?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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