首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >虚拟表指针

虚拟表指针
EN

Stack Overflow用户
提问于 2014-05-19 19:56:19
回答 2查看 918关注 0票数 2

我决定了解vtable是如何构建的,我打开了调试器,发现了一些奇怪的事情。节点ptr包含一些vptr。我一直认为每个对象只有一个vptr。有人能跟我解释一下这是怎么回事吗?(我指基类指针指向派生类的对象时)

代码语言:javascript
复制
#include <iostream>
using namespace std;

class Base
{
    int base;
public:
    virtual void say()
    {
        cout << "Hello" << endl;
    }
    virtual void no()
    {
        cout << "No" << endl;
    }
};


class Base2
{
public:
    virtual void lol()
    {
        cout << "lol" << endl;
    }
};

class Derv:public Base,public Base2
{
public:
    void say()
    {
        cout << "yep" << endl;
    }

};


int main()
{

    Base* ptr = new Derv();
    ptr->say();
    ptr = new Base();
    ptr->say();
}

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2014-05-19 20:27:56

需要两个指针,因为有两个带有虚拟函数的基类。

让我们一步一步地看一遍:

首先定义具有虚拟函数的Base。因此,编译器将创建一个虚拟表,大致如下(括号中给出的索引;请注意,这是一个示例,确切的表布局将取决于编译器):

代码语言:javascript
复制
[0] address of Base::say()
[1] address of Base::no()

Base布局中,将有一个字段__vptr (或者不管它是如何命名的,如果它被命名的话)指向该表。当给定类型为pBase的指针Base*并要求调用say时,编译器实际上将调用(p->__vptr[0])()

接下来,定义第二个独立类Base2,其虚拟表如下所示:

代码语言:javascript
复制
[0] address of Base2::lol()

通过lol指针对Base2的调用现在将转换为类似于(pBase2->__vptr[0])()的内容。

现在,您终于定义了一个类Derv,它继承自BaseBase2。这尤其意味着您可以让Base*Base2*同时指向Derv类型的对象。现在,如果只有一个__vptrpBase->say()pBase2->lol()将调用相同的函数,因为它们都转换为(pXXX->__vptr[0])()

然而,实际发生的情况是,有两个__vptr字段,一个用于Base基类,一个用于_Base2基类。Base*用它的__vptr指向Base子对象,Base2*用它自己的__vptr指向Base2子对象。现在,Derv虚拟表看起来可能如下所示:

代码语言:javascript
复制
[0] address of Derv::say()
[1] address of Base::no()
[2] address of Base2::lol()

__vptrBase子对象指向该表的开头,而Base2子对象的__vptr指向元素[2]。现在调用pBase->say()将转换为(pBase->__vptr[0])(),并且由于Base子对象的__vptr指向Derv虚拟表的开头,因此它将按预期的方式调用Derv::say()。另一方面,如果调用pBase2->lol(),它将被转换为(pBase2->__vptr[0])(),但是由于pBase2指向Base2子代码>d48,因此它将取消相应的D 49,后者指向D 50Derv的虚拟表,其中存储D52的地址。因此,现在Base2::lol()被称为预定地址。

票数 4
EN

Stack Overflow用户

发布于 2014-05-19 20:09:54

想想看,当将指针转换为指向基的指针时,它必须引用与基类型具有相同布局的内存块。当您拥有多个继承时,您将在每个具有虚拟函数的基中得到一个vptr。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/23746150

复制
相关文章

相似问题

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