Шрифт:
Здесь мы вызываем виртуальную функцию (
Для получения непревзойденно гибких и высокопроизводительных программ.
• Используйте шаблоны, когда производительность программы играет важную роль (например, при интенсивных вычислениях в реальном времени; подробнее об этом речь пойдет в главах 24 и 25).
• Используйте шаблоны, когда гибкость сочетания информации, поступающей от разных типов, играет важную роль (например, при работе со стандартной библиотекой языка C++; эта тема будет обсуждаться в главах 20 и 21).
При компиляции программы, использующей шаблоны, компилятор “заглядывает” внутрь шаблонов и его шаблонных аргументов. Он делает это для того, чтобы извлечь информацию, необходимую для генерирования оптимального кода. Для того чтобы эта информация стала доступной, современные компиляторы требуют, чтобы шаблон был полностью определен везде, где он используется. Это относится и к его функциям-членам и ко всем шаблонным функциям, вызываемым из них. В результате авторы шаблонов стараются разместить определения шаблонов в заголовочных файлах. На самом деле стандарт этого не требует, но пока не будут разработаны более эффективные реализации языка, мы рекомендуем вам поступать со своими шаблонами именно так: размещайте в заголовочном файле определения всех шаблонов, используемых в нескольких единицах трансляции.
19.3.3. Контейнеры и наследование
Это одна из разновидностей сочетания объектно-ориентированного и обобщенного программирования, которое люди постоянно, но безуспешно пытаются применять: использование контейнера объектов производного класса в качестве контейнера объектов базового класса. Рассмотрим пример.
Итак, попытаемся снова использовать указатели.
И вновь система типов сопротивляется. Почему? Рассмотрим, что может делать функция