首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >vtable:底层算法

vtable:底层算法
EN

Stack Overflow用户
提问于 2017-04-17 11:02:37
回答 1查看 282关注 0票数 8

我对vtable的理解是,如果我有一个带虚拟函数的类Cat与Lion和HouseCat子类对话(),那么就有一个vtable,它将the ()映射到每个子类的正确实现。所以打个电话

代码语言:javascript
复制
cat.speak()

编译成

代码语言:javascript
复制
cat.vtable[0]()

也就是说,在vtable位置0中进行查找,并在此位置调用函数指针。

我的问题是:多重继承会发生什么?

让我们添加一个类宠物。宠物有虚拟函数-- speak()和eat()。HouseCat扩展宠物,而狮子没有。现在,我需要确保

代码语言:javascript
复制
pet.eat()

编译为

代码语言:javascript
复制
pet.vtable[1]()

那就是vtable需要说()。Pet.eat需要是插槽1,这是因为cat.speak()需要访问vtable中的插槽0,如果对于HouseCat,插槽0恰好是吃的,这将是非常错误的。

编译器如何确保vtable索引配合在一起?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-05-03 04:18:33

规范没有设置任何内容,但是编译器通常会为每个直接的非虚拟基类生成一个vtable,为派生类生成一个vtable,然后将第一个基类的vtable和派生类的vtable合并。

因此,更具体地说,编译器在构造类时生成的内容:

  • 猫 vptr \ Cat字段: speak()
  • 宠物 vptr \ Pet字段: eat()
  • 狮子 vptr = Cat字段\ Lion字段: speak()
  • HouseCat vptr \ Cat字段\ vptr \vptr\ Pet字段\ HouseCat字段: speak():eat()

编译器在调用/转换时生成的内容(变量名是静态类型名称):

  • cat.speak()
    • obj[0][0]() -对猫、狮和HouseCat的“猫”部分有效

  • pet.eat()
    • obj[0][0]() -对宠物和HouseCat的“宠物”部分有效

  • lion.speak()
    • obj[0][0]() -对狮子有效

  • houseCat.speak()
    • obj[0][0]() -对HouseCat的“猫”部分有效

  • houseCat.eat()
    • obj[Cat size][0]() -对HouseCat的“宠物”部分有效

  • (Cat)houseCat
    • obj

  • (Pet)houseCat
    • obj + Cat size

因此,我想让您感到困惑的关键是:(1)多个vtable是可能的,(2) upcast实际上可能返回不同的地址。

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

https://stackoverflow.com/questions/43450179

复制
相关文章

相似问题

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