Языки программирования - концепции и принципы

потому что изменение, которое состоит


Это различие весьма сущест­венно, потому что изменение, которое состоит в замене невиртуальной под­программы на виртуальную подпрограмму или обратно, может вызвать ошиб­ки во всем семействе классов, полученных из базового.

Динамическая диспетчеризация в языке C++ рассчитана на вызовы вир­туальных подпрограмм, осуществляемые через указатель или ссылку.

 

 

Реализация

    Ранее мы отмечали, что если подпрограмма не найдена в производном клас­се, то поиск делается в предшествующих классах, пока не будет найдено опре­деление подпрограммы. В случае статического связывания поиск можно де­лать во время компиляции: компилятор просматривает базовый класс произ­водного класса, затем его базовый класс, и так далее, пока не будет найдено соответствующее связывание подпрограммы. Затем для этой подпрограммы может компилироваться обычный вызов процедуры.

    Если используются виртуальные подпрограммы, ситуация усложняется, потому что фактическая подпрограмма, которая должна быть вызвана, не из­вестна до времени выполнения. Обратите внимание, что, если виртуальная подпрограмма вызывается с объектом конкретного типа, в противополож­ность ссылке или указателю, то все еще может использоваться статическое связывание. С другой стороны, решение, какую именно подпрограмму следу­ет вызвать, основано на 1) имени подпрограммы и 2) классе объекта. Но первое известно во время компиляции, поэтому нам остается только смодели­ровать case-оператор по классам.

   Обычно реализация выглядит немного иначе; для каждого класса с вирту­альными подпрограммами поддерживается таблица диспетчеризации (см. рис. 14.5). Каждое значение класса должно «иметь при себе» свой индекс для входа в таблицу диспетчеризации для порождающего семейства, в котором оно определено. Элементы таблицы диспетчеризации являются указателями на таблицы переходов; в каждой таблице переходов содержатся адреса входов в виртуальные подпрограммы. Обратите внимание, что два элемента таблицы переходов могут указывать на одну и ту же процедуру; это произойдет, когда класс не замещает виртуальную подпрограмму.

Содержание  Назад  Вперед