Стандарты программирования на С++. 101 правило и рекомендация | страница 113
Динамический полиморфизм предстает перед нами в форме классов с виртуальными функциями и объектов, работа с которыми осуществляется косвенно — через указатели или ссылки. Статический полиморфизм включает шаблоны классов и функций.
Полиморфизм означает, что данное значение может иметь несколько типов, а данная функция может принимать аргументы типов, отличающихся от точных типов ее параметров. "Полиморфизм представляет собой способ получить немного свободы динамической проверки типов, не теряя преимуществ статической проверки" — [Webber03].
Сила полиморфизма состоит в том, что один и тот же фрагмент кода может работать с разными типами, даже с теми, которые не были известны в момент написания этого кода. Такая "применимость задним числом" является краеугольным камнем полиморфизма, поскольку существенно увеличивает пригодность и возможность повторного использования кода (см. рекомендацию 37). (В противоположность этому мономорфный код работает только со строго конкретными типами, теми, для работы с которыми он изначально создавался.)
Динамический полиморфизм позволяет значению иметь несколько типов посредством открытого наследования. Например, >Derived* p
можно рассматривать как указатель не только на >Derived
, но и на объект любого типа >Base
, который прямо или косвенно является базовым для >Derived
(свойство категоризации). Динамический полиморфизм известен также как включающий полиморфизм, поскольку множество, моделируемое >Base
, включает специализации, моделируемые >Derived
.
Благодаря своим характеристикам динамический полиморфизм в С++ наилучшим образом подходит для решения следующих задач.
• Единообразная работа, основанная на отношении надмножество/подмножество. Работа с различными классами, удовлетворяющими отношению надмножество/подмножество (базовый/производный), может выполняться единообразно. Функция, работающая с объектом >Employee
(Служащий), будет работать и с объектами >Secretary
(Секретарь).
• Статическая проверка типов. В С++ все типы проверяются статически.
• Динамическое связывание и раздельная компиляция. Код, который использует иерархию классов, может компилироваться отдельно от этой иерархии. Это становится возможным благодаря косвенности, обеспечиваемой указателями (как на объекты, так и на функции).
• Бинарная согласованность. Модули могут компоноваться как статически, так и динамически, до тех пор, пока схемы виртуальных таблиц подчиняются одним и тем же правилам.