|
Программирование >> Немодифицирующие последовательные алгоритмы
немодифицирующие последовательные алгоритмы Как легко догадаться из названия, стандартная библиотека шаблонов (STL) основывается на относительно новом понятии шаблона. Поэтому мы начнем с краткого обсуждения этого предмета. Шаблонные функции Предположим, что для некоторого положительного числам:нам приходится часто вычислять значение выражения 2 * X + (X * X + 1) / (2 * X) где X может быть типа double или int. В последнем случае оператор деления / обозначает целочисленное деление, дающее целый результат. Например, если X имеет тип double и равен 5.0, тогда значение приведенного выражения составляет 12.6, но если х имеет тип int и равен 5, то значение выражения будет 12. Вместо того чтобы писать две функции, такие как double f(double х) { double х2 = 2 * х; return х2 + (х * X + 1)/х2; int f(int x) { int x2 = 2 * x; return x2 + (x * X + l)/x2; нам достаточно создать один шаблон, как показано в следующем примере, который представляет собой законченную программу: ftempi.срр: Шаблонная функция. #include <iostream.h> template <class Т> Т f(T х) { Т х2 = 2 * х; return х2 + (х * X + 1)/х2; int main О { cout f(5.0) << endl f(5) endl; return 0; Программа выведет 12.6 12 В этом шаблоне Т - тип, задаваемый аргументом при вызове/. При вызове /(5.0) Т будет обозначать double (это тип константы 5.0), так что, к примеру, в выражении {х* х+ \)/х2 выполнится деление с плавающей точкой. Напротив, при исполнении вызова/(5) Т будет обозначать тип int, что приведет к целочисленному делению. При разборе программы ftempl.cpp компилятор создает две различные функции, весьма похожие на функции /{double) и f{int), с которых мы начинали наш пример. Следовательно, компилятор должен одновременно видеть как определения, так и вызовы шаблонов. Это делает шаблоны плохими кандидатами на раздельную компиляцию; вместо этого мы, как правило, помещаем шаблоны в файлы заголовка. Когда мы используем файлы заголовка, написанные кем-то другим, мы не видим определения шаблонов и вызываем их как обычные функции, что показано на примере вызовов /(5.0) и/(5) в нашей программе. Поэтому, применяя шаблоны функций STL, мы можем и не знать, что вызываем функции, созданные из шаблонов. Что в имени? Шаблон, который, подобно рассмотренному выше, начинается со слова template, а заканчивается закрывающей фигурной скобкой, следующей за оператором return, создателем языка Бьерном Страуструпом был изначально назван шаблоном функции. Данный термин отражает, что мы имеем дело с определенным видом шаблона, отличающимся от шаблонов классов, о которых речь пойдет ниже. Сегодня многие авторы используют вместо этого выражение шаблонная функция (template funcion), потому что шаблоны указанного типа очень похожи на обычные функции. В этой книге мы также будем использовать термин шаблонная функция, а иногда даже просто функция для обозначения этих шаблонов. То же относится и к обсуждаемому ниже понятию, которое изначально получило наименование шаблон класса, а в книге зовется шаблонным классом (template class) или просто классом. Шаблонные классы Мы можем использовать тип как параметр (Гв предыдущем примере) для классов почти так же, как и для функций. Предположим, нам нужен класс Pair, чтобы хранить пары значений. Иногда оба значения принадлежат к типу double, иногда к типу int. Тогда вместо двух новых классов, к примеру, class PairDouble { public: PairDouble(double xl, double yl): x(xl), y(yl) {} void showQ(); private: double X, y; void PairDouble::showQ() { cout x/y endl; } после чего следует аналогичный фрагмент с классом Pairint, нам достаточно написать один шаблонный класс: II cltempl.cpp: Шаблонный класс. #include <iostream.h> template <class Т> class Pair { public: Pair(T xl, Tyl): x(xl), y(yl){} void showQ(); private: T X, y; template <class T>
|
© 2006 - 2024 pmbk.ru. Генерация страницы: 0.001
При копировании материалов приветствуются ссылки. |