Я прочитал пример о полиморфизме, который выглядит ниже, где show () — это виртуальная функция:
int main()
{
Derived dv1;
Derived dv2;
Base* ptr;
ptr = &dv1;
ptr->show();
ptr = &dv2;
ptr->show();
}
В книгах говорится, что в этом случае компилятор будет использовать late binding
техника. Я понимаю разницу между поздним связыванием и ранним связыванием. Тем не менее, в этом примере мы (и, возможно, также и компилятор) можем видеть, какую функцию следует вызывать, потому что нет никаких изменений в объектах, которые ptr
указывает на. Так почему бы не раннее связывание в этом случае, потому что позднее связывание вызовет некоторые накладные расходы?
Однако в этом примере мы (и, возможно, также и компилятор) можем видеть, какую функцию следует вызывать, потому что нет изменений в объектах, на которые указывает ptr.
Правильный.
Так почему бы не раннее связывание в этом случае, потому что позднее связывание вызовет некоторые накладные расходы?
Функция вызывается через указатель на полиморфный тип, поэтому используется позднее связывание.
Позднее связывание просто означает, что вызов будет преобразован в самое производное переопределение (вплоть до конкретного типа объекта), а не в разрешение вызова Base::show
,
Конечно, динамическая диспетчеризация может быть необходима для позднего связывания в целом, но реализация может нарушать правила, если программа все еще ведет себя так же, как если бы она следовала правилам. Это известно как как будто править. И благодаря тому наблюдению, которое вы также сделали, изменение программы на статическую диспетчеризацию не меняет поведения, поэтому компилятору разрешается оптимизировать и избегать динамической диспетчеризации.
Других решений пока нет …