如何在多态语言中找到正确的函数指针?

问题描述 投票:0回答:1

假设我们有类似 Java 语言的接口:

interface Animal {
  public int getAge();
}

interface Tamable {
  public void tame();
}

那些接口是由类实现的:

class Cat implements Animal { // Cats are not tamable
  public int getAge() {      // this method is somewhere in memory (e.g. at 0xf000)
    // ...
  }
}

class Dog implements Animal, Tamable {
  public int getAge() {      // this method is somewhere in memory (e.g. at 0xf008)
    // ...
  }
  public void tame() {       // this method is somewhere in memory (e.g. at 0xf00e)
    // ...
  }
}

将接口

Tamable
传递给其他方法时,如下所示:

  void pet(Tamable tamable) {
    tamable.tame();          // <-- this call
    // ...
  }

我们怎么知道调用

tame()
时要跳转到哪个内存地址? VMT(Virtual Method Table)在这种情况下是如何实现的?

我能想象它们被实现的唯一方法是一些哈希表,但这似乎会使虚拟调度非常慢。

如果 VMT 只是函数指针的数组/向量,那么编译器如何知道在类

tame()
上使用什么偏移量来获取函数指针
Dog
,在调度调用时,在编译时它无法在任何时候解析
 tamable
会是
Dog
还是
Cat

(注意:Java 只是作为示例使用,我正在寻找更通用的答案)

任何建议都会有所帮助。我在互联网上找到的所有资源都非常模糊地描述了如何实现 VMT 以及如何获得 VMT 的密钥。

compiler-construction compiler-optimization
1个回答
1
投票

对于每个实现的接口,类的对象包含指向该接口的 VMT 的指针(所谓的

vptr
)。每当你调用一个将接口作为参数的函数时(比如你的情况下的
pet
),这个指针就会在幕后传递。

每个 VMT 只是一个函数指针数组。表中每个方法的索引由编译器根据接口声明中方法的顺序静态分配。

© www.soinside.com 2019 - 2024. All rights reserved.