Почему именно компиляторы не могут определить истинный тип переменной до времени выполнения?

Я часто слышу о том, что компиляторы не могут определить точную реализацию метода при определенных условиях. Пример Fox, мы можем представить сценарий (так говорят люди), где для родительского класса с методом foo(), который был переопределен в дочернем классе, компилятор не будет теперь, какую реализацию foo() вызывать до времени выполнения. Следовательно, у нас есть понятия динамической отправки, vtables и т. Д.

Мой вопрос, почему именно компилятор не может определить точную реализацию для вызова? Я перестал думать об этом в последнее время, и я изо всех сил пытался оправдать это. Возможно, есть что-то действительно очевидное, что я упускаю (вероятно, я пну себя, когда услышу ответ). Это только из-за внешних обстоятельств? Если так, то как бы это закончилось?

Является ли это языковым ограничением или есть что-то более фундаментальное?

2 ответа

Решение

Думать об этом:

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() вызывать во время компиляции, так как выбор зависит исключительно от ввода пользователя. Диспетчеризация осуществляется через виртуальную таблицу функций и выполняется во время выполнения.

Компилятор не имеет ничего общего со временем выполнения, за исключением того, что он подготавливает машинный код, который фактически выполняется.

Когда объект создается динамически и имеет полиморфные свойства, а функция получает параметр типа суперкласса, тип не известен PROGRAM, пока он не будет передан.

Другие вопросы по тегам