为什么静态解析虚方法调用如此困难?

时间:2011-04-18 12:10:49

标签: oop programming-languages static-analysis virtual-method

假设我们有以下伪代码。我说的是OO语言。

class A{

    foo(){...}

}

class B extends A{

    foo(){...}

}

class C extends B{

    foo(){...}
}

static void f(A a)
{

    A a=new A();
    a=new B();
    a.foo();

}

我们很容易认识到a.foo()在类B中调用了函数foo。那么为什么编译器很难通过静态分析得到这个真理呢?这里的基本问题是为什么静态地确定A的类型对编译器来说很难?

2 个答案:

答案 0 :(得分:3)

您发布的示例非常简单,并且不显示需要虚拟方法调用的任何内容。使用相同的类,检查此函数;

void bar(A* a) {
  a->foo();
}

如果aBC或普通A的实例,则编译器无法在编译时告知。这只能在一般情况下在运行时决定。

编译器甚至无法知道是否会在将来与A派生的新类与此代码链接。

答案 1 :(得分:2)

想象一下:

A a = createInstanceFromString("B");

现在你搞砸了。

严肃地说,你的例子太简单了。想象一下,如果赋值的右侧是对某个其他“模块”中定义的函数的调用(无论这意味着什么)。这意味着编译器必须检查所有执行路径以确定返回值的确切类型,但这非常昂贵,有时甚至是不可能的。