Стандарты программирования на С++. 101 правило и рекомендация | страница 114
Статический полиморфизм посредством шаблонов также позволяет значению иметь несколько типов. Внутри шаблона
>template
>t
может иметь любой тип, который можно подставить в >f
для получения компилируемого кода. Это называется "неявным интерфейсом" в противоположность явному интерфейсу базового класса. Таким образом достигается та же цель полиморфизма — написание кода, который работает с разными типами — но совершенно иным путем.
Статический полиморфизм наилучшим образом подходит для решения следующих задач.
• Единообразная работа, основанная на синтаксическом и семантическом интерфейсе. Работа с типами, которые подчиняются синтаксическому и семантическому интерфейсу, может выполняться единообразно. Интерфейсы в данном случае представляют синтаксическую сущность и не основаны на сигнатурах, так что допустима подстановка любого типа, который удовлетворяет данному синтаксису. Например, пусть дана инструкция >int i = p->f(5);
. Если >p
— указатель на класс >Base
, эта инструкция вызывает определенную функцию интерфейса, вероятно, >virtual int f(int)
. Но если >p
имеет обобщенный тип, то этот вызов может быть связан со множеством различных вещей, включая, например, вызов перегруженного оператора >operator->
, который возвращает тип, в котором определена функция >X f(double)
, где >X
— тип, который может быть преобразован в int.
• Статическая проверка типов. Все типы проверяются статически.
• Статическое связывание (мешает раздельной компиляции). Все типы связываются статически.
• Эффективность. Вычисления во время компиляции и статическое связывание позволяют достичь оптимизации и эффективности, недоступных при динамическом связывании.
Определите ваши приоритеты и используйте каждый вид полиморфизма там, где проявляются его сильные стороны.
Следует сочетать статический и динамический полиморфизм для того, чтобы получить преимущества обоих видов полиморфизма, а не для того, чтобы комбинировать их недостатки.
• Статика помогает динамике. Используйте статический полиморфизм для реализации динамически полиморфных интерфейсов. Например, у вас может быть абстрактный базовый класс >Command
, и вы определяете различные реализации в виде шаблона
>template* ... */> class ConcreteCommand: public Command
В качестве примеров можно привести реализации шаблонов проектирования >Command
и >Visitor
(см. [Alexandrescu01] и [Sutter04]).
• Динамика помогает статике. Обобщенный, удобный, статически связываемый интерфейс может использовать внутреннюю динамическую диспетчеризацию, что позволяет обеспечить одинаковую схему размещения объектов. Хорошими примерами могут служить реализации размеченных объединений (см. [Alexandrescu02b] и [Boost]) и параметр