3

我正在为我编写的虚拟机开发面向对象语言的编译器,该虚拟机用作跨平台抽象层。我对继承的方法如何工作感到有些困惑。假设我有以下几行 C# 代码。

class myObject : Object {
public int aField;
public override string ToString() { 
    return "Dis be mah object";
} 
public void regularMethod() { }
}
Object test = new myObject();
Console.WriteLine(test.ToString());

现在这将输出'Dis be mah object'。如果我调用 regularMethod 但是编译的代码实际上会做这样的事情:

struct myObject {
    public int aField;
}

public static void regularMethod(ref myObject thisObject)
{
}

编译后继承的方法 ToString 怎么处理?编译器无法执行我在上面使用常规方法所做的事情,因为如果这样做了,那么仅在创建 myObject 类型而不是普通 Object 类型时才会返回“Dis be mah object”。我的猜测是 struct myObject 将包含一个函数指针/委托,该函数指针/委托将在创建新实例时分配。

4

1 回答 1

1

如果您正在处理静态重载,那真的很简单:在处理代码时绑定到正确的实现。

但是,如果您使用动态重载,则必须在运行时决定。为此,您需要使用动态调度,使用真实的对象类型。这与方法覆盖相同。

动态调度与后期绑定不同。在这里,您选择的是实现而不是操作的名称(尽管此绑定将在编译时发生,但实现只会在运行时发生)。

静态地,您只会绑定到对象声明类型的实现。它在编译时完成。

您可以使用一些机制来实现动态移情,它将决定您的语言范式。

你的语言是打字的吗?弱打字?

例如,C++ 提供了我提到的两种类型的调度。对于动态的(我相信这是您感兴趣的),它使用一个虚拟表来为一个类进行映射。该类的每个实例都将指向一个指向该 vtable 的指针。

  • 实施

vtable(一个用于同一类的所有对象)将具有所有动态绑定方法的地址。当进行呼叫时,将从该表中获取其中一个地址。类型兼容对象的表的地址对于所有兼容类的方法具有相同的偏移量。

希望我有所帮助。

于 2013-06-15T02:54:15.070 回答