我经常听说编译器在某些条件下无法确定要使用的方法的确切实现。 Fox的例子,我们可以想象一个场景(所以人们说),对于一个父类有一个方法foo()已经在子类中重写,编译器现在不会调用哪个foo()实现直到运行时。因此,我们有动态调度,vtable等概念。
我的问题是,为什么编译器无法确定要调用的确切实现?我最近停下来想一想,我一直在努力证明这一点。也许有一些非常明显的东西我想念(当我听到答案时,我可能会踢自己)。这只是外部环境吗?如果是这样,那将如何发挥出来?
这是一种依赖于语言的限制还是有更基本的东西?
答案 0 :(得分: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()
,因为选择完全取决于用户输入。调度通过函数虚拟表完成,并在运行时完成。
答案 1 :(得分:0)
编译器与运行时没有任何关系,只是它准备了实际运行的机器代码。
当动态创建对象并具有多态属性,并且函数获取超类类型的参数时,PROGRAM不知道该类型,直到传入该类型。