Виртуальные методы реализованы с помощью таблицы виртуальных методов (VMT). Для каждого класса есть один VMT. VMT содержит одну запись для каждого виртуального метода в классе. И эта запись является адресом метода.
Это позволяет очень эффективно звонить. Вы просто получаете адрес VMT, который находится с фиксированным смещением от Self
. Затем вы просматриваете указатель метода по индексу и вызываете метод.
Это означает, что если у вас есть класс с большим количеством виртуальных методов, и вы получите подкласс, вы создадите новый VMT со всеми виртуальными методами. И если вы не переопределили многие из них, вы обнаружите, что VMT имеют много перекрытий.
Это имело значение в дни 16 бит. VMT могут занимать много места в исполняемом изображении (это то, что подразумевается под размером кода), и вы могли бы вырваться из пространства для VMT. Так были введены динамические методы. Аналогом VMT является таблица динамических методов, DMT. Это выполняется по-разному, чтобы избежать повторения, когда методы не переопределены. Недостатком является то, что вызов динамических методов дороже.
В настоящее время, поскольку 32-разрядные, и особенно с очень толстыми исполняемыми файлами, которые производит Delphi, эти проблемы с размером не имеют значения. И поэтому все разумные советы - использовать исключительно виртуальные методы.
Реализации таблиц виртуальных методов хорошо поняты, и их можно найти много, чтобы понять их. Это тем более для динамических методов, которые довольно странны. Лучшие источники информации, которую я нашел в блоге от Hallvard Vassbotn в:
Две цитаты говорят вам, что вам нужно знать. Ибо, на мой взгляд, всегда используется виртуальное. –
@DavidHeffernan Сообщение отредактировано! – EProgrammerNotFound