虚拟函数表何时设置为0

When is the virtual function table set to 0

本文关键字:设置 何时 函数 虚拟      更新时间:2023-10-16

我正在分析我们的应用程序中发生的访问冲突,因为它试图在虚拟函数表指向0的对象上调用虚拟函数。所以我想知道,在对象的生命周期中,虚拟函数表指针在什么时候没有设置或显式设置为零?

(我们使用Visual C++10作为编译器。)

当对象处于有效状态时,vtable指针永远不会为0。在构造和销毁过程中,当对象具有抽象基类的动态类型时,vtable将指向抽象基类vtable,该抽象基类将包括纯虚拟函数,但vtable指针本身仍将为非零。

vtable指针唯一可以为零的时间是在构造之前或销毁之后。

如果vtable指针真的为零,那么您可能使用了VC++扩展,例如:

class __declspec(novtable) Base {
public:
    Base();
    virtual void proc();
};

这里__declspec(novtable)告诉编译器该类不需要vtable,因为在派生类安装了自己的vtable之前,不会对其调用虚拟函数。如果在此之前调用Base::proc(),则可能会出现错误。

更可能的是,vtable本身是非零的,但函数在其中的槽是零,因为函数是纯虚拟的:

class Base {
public:
    virtual void proc() = 0;
};

然后有人用类似的代码称之为

void Derived::proc() {
    Base::proc();
    // Derived-specific stuff here.
};

这可能是因为Derived的作者认为他们的覆盖需要调用基本版本,即使基本版本不存在。

不管怎样,找到它的一种方法是停止所有基类的恶作剧,正常定义函数,看看是什么调用它

class Base {
public:
    virtual void proc() {
        assert( typeof(*this) != typeof(Base) ); // Break-point here.
    }
};