繁体   English   中英

为什么这不是纯虚函数的调用?

[英]Why is this not a call of a pure virtual function?

我试图在这个答案中 “修复”这个例子,以演示如何调用纯虚函数。

#include <iostream>
using namespace std;

class A
{
    int id;
public:
    A(int i): id(i) {}
    int callFoo() { return foo(); }
    virtual int foo() = 0;
};

class B: public A
{
public:
    B(): A(callFoo()) {}
    int foo() { return 3; }
};

int main() {
    B b; // <-- this should call a pure virtual function
    cout << b.callFoo() << endl;
    return 0;
}

但是我没有得到运行时错误(使用C ++ 4.9.2) ,但输出3.我尝试使用Borland C ++ 5.6.4,但是我遇到了访问冲突。 我认为foo()在基类的构造函数的调用中应该是纯虚拟的。

谁错了? 我应该尝试更多的编译器吗? 我是否正确理解虚函数?

您的代码具有未定义的行为:在初始化所有基类之前,在对象(甚至是非虚拟对象)上调用成员函数是UB。 C ++ 14(n4140)12.6.2 / 14,强调我的:

可以为正在构造的对象调用成员函数(包括虚拟成员函数,10.3)。 类似地,正在构造的对象可以是typeid运算符(5.2.8)或dynamic_cast (5.2.7)的操作数。 但是,如果在基类的所有mem-initializer完成之前,在ctor-initializer (或直接或间接从ctor-initializer调用的函数)中执行这些操作,则操作的结果是不确定的。 ...

ctor-initializer是以下整个列表: mem-initializer是此列表的一个元素。

声明B b; 将默认构造函数调用到B

当构建B ,没有相关的B构建,直到A被完全构造。

因此,在尝试调用callFoo() ,行为是未定义的,因为您不能依赖v-table来设置B类。

总结:在构造抽象类期间调用纯虚函数的行为是未定义的。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM