Слежение заключается в сокрытии метода базового класса с новым определением в дочернем классе.
Разница между скрытием и переопределением связана со способом вызова методов.
Таким образом, когда виртуальный метод переопределяется, адрес вызова для таблицы вызовов метода базового класса заменяется адресом дочерней подпрограммы.
С другой стороны, когда метод скрыт, новый адрес добавляется в таблицу вызовов методов дочернего класса.
Когда выполняется вызов данного метода:
- Тип класса таблицы вызова метода получается, если мы вызываем ссылку на базовый класс, то получается таблица метода базового класса, если у нас есть ссылка на дочерний класс, то получается таблица метода дочернего класса .
- Метод ищется в таблице, если он найден, то происходит вызов, в противном случае ищется таблица методов базового класса.
Если мы вызовем метод со ссылкой на дочерний класс, то поведение будет таким же, если метод был переопределен, адрес метода будет найден в базовом классе, если метод был скрыт, адрес метода будет найден в дочернем классе, и поскольку он уже найден, таблица базового класса не будет найдена.
Если мы вызовем метод со ссылкой на базовый класс, поведение изменится. При переопределении, так как адрес метода перезаписывает запись базового класса, мы будем вызывать дочерний метод, даже если удерживается ссылка на базовый класс. При теневом копировании таблица методов базового класса (которая является единственной видимой, поскольку мы храним ссылку на базовый класс) содержит адрес виртуального метода, и поэтому будет вызываться метод базового класса.
В общем, теневое копирование - плохая идея, поскольку оно вводит различие в поведении экземпляра в зависимости от ссылки на него.