2

我经常听说编译器在某些条件下无法确定要使用的方法的确切实现。Fox 的例子,我们可以想象一个场景(人们说),对于一个父类的方法 foo() 已经在子类中被覆盖,编译器现在不会调用 foo() 的哪个实现,直到运行时。因此,我们有了动态调度、vtables 等的概念。

我的问题是,究竟为什么编译器不能确定要调用的确切实现?我最近停下来思考它,我一直在努力证明它的合理性。也许我错过了一些非常明显的东西(当我听到答案时,我可能会踢自己)。仅仅是因为外部环境吗?如果是这样,那将如何发挥作用?

这是语言相关的限制还是手头有更基本的东西?

4

2 回答 2

11

想一想:

class Base
{
public:
    virtual void some_virtual_method(){...}
};
class Derived: public Base
{
public:    
    void some_virtual_method() override{...}
};

int choice;
cin >> choice; // cannot know the value at compile time

Base* foo;

if(choice)
{
    foo = new Base;
}
else
{
    foo = new Derived;
}

foo->some_virtual_method();

编译器无法知道some_virtual_method()在编译时调用哪个,因为选择完全取决于用户输入。调度是通过函数虚表完成的,它是在运行时完成的。

于 2014-12-10T22:41:32.457 回答
0

编译器与运行时没有任何关系,除了它准备实际运行的机器代码。

当一个对象被动态创建并具有多态属性,并且一个函数获取超类类型的参数时,PROGRAM 不知道该类型,直到它被传入。

于 2014-12-10T22:44:12.380 回答