首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >虚拟函数表何时设置为0

虚拟函数表何时设置为0
EN

Stack Overflow用户
提问于 2012-08-01 17:28:15
回答 2查看 353关注 0票数 2

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

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

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2012-08-01 17:33:54

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

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

票数 3
EN

Stack Overflow用户

发布于 2012-08-01 19:46:09

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

代码语言:javascript
复制
class __declspec(novtable) Base {
public:
    Base();
    virtual void proc();
};

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

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

代码语言:javascript
复制
class Base {
public:
    virtual void proc() = 0;
};

然后有人用这样的代码调用了它:

代码语言:javascript
复制
void Derived::proc() {
    Base::proc();
    // Derived-specific stuff here.
};

这可能是因为派生的作者假设他们的覆盖需要调用基础版本,即使基础版本不存在。

无论哪种方式,找到它的一种方法是停止所有基类恶作剧,正常定义函数,并查看调用它的是什么。例如:

代码语言:javascript
复制
class Base {
public:
    virtual void proc() {
        assert( typeof(*this) != typeof(Base) ); // Break-point here.
    }
};
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/11756372

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档