我对vtable的理解是,如果我有一个带虚拟函数的类Cat与Lion和HouseCat子类对话(),那么就有一个vtable,它将the ()映射到每个子类的正确实现。所以打个电话
cat.speak()编译成
cat.vtable[0]()也就是说,在vtable位置0中进行查找,并在此位置调用函数指针。
我的问题是:多重继承会发生什么?
让我们添加一个类宠物。宠物有虚拟函数-- speak()和eat()。HouseCat扩展宠物,而狮子没有。现在,我需要确保
pet.eat()编译为
pet.vtable[1]()那就是vtable需要说()。Pet.eat需要是插槽1,这是因为cat.speak()需要访问vtable中的插槽0,如果对于HouseCat,插槽0恰好是吃的,这将是非常错误的。
编译器如何确保vtable索引配合在一起?
发布于 2017-05-03 04:18:33
规范没有设置任何内容,但是编译器通常会为每个直接的非虚拟基类生成一个vtable,为派生类生成一个vtable,然后将第一个基类的vtable和派生类的vtable合并。
因此,更具体地说,编译器在构造类时生成的内容:
编译器在调用/转换时生成的内容(变量名是静态类型名称):
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实际上可能返回不同的地址。
https://stackoverflow.com/questions/43450179
复制相似问题