Информационный сайт

 

Реклама
bulletinsite.net -> Книги на сайте -> Программисту -> Лафоре Р. -> "Объектно-ориентированное программирование в С++" -> 244

Объектно-ориентированное программирование в С++ - Лафоре Р.

Лафоре Р. Объектно-ориентированное программирование в С++ — М.: Питер, 2004. — 992 c.
Скачать (прямая ссылка): obektnoorentprogramm2004.djvu
Предыдущая << 1 .. 238 239 240 241 242 243 < 244 > 245 246 247 248 249 250 .. 341 >> Следующая


Обратите внимание, что количество экземпляров шаблонной функции в памяти резко возрастает с ростом числа аргументов шаблона. Уже два разных аргумента в сочетании с шестью базовыми типами приводят к созданию в памяти 36 копий функции. Функции бывают довольно большими, и могут возникнуть проблемы с тем, что программе требуется слишком много памяти. С другой стороны, не всегда реально вызываются шаблонные функции, несмотря на наличие их шаблонов. . .... Шаблоны классов 647

А почему не макросы?

Старосветские программисты, пишущие на С, снова удивятся, почему же мы не используем макросы для создания функций, работающих с разными типами данных? Например, функция abs() могла бы быть определена так:

!define abs(n) ( (n<0) ? (-n) : (n) )

Это возымело бы тот же эффект, что и от шаблона класса в TEMPABS, потому что здесь используется простое замещение одного текста на другой, а значит, можно указывать любые типы данных. Тем не менее, как уже отмечалось ранее, макросы редко используются в С++. С ними возникают некоторые проблемы. Одна из них заключается в том, что макросы не осуществляют проверку типов. Может быть несколько переменных макроса, которые обязаны быть одного типа, но компилятор не проверяет это условие. Еще одна проблема состоит в том, что не указан тип возвращаемого значения, поэтому компилятор, опять же, не может проверить корректность присваивания. В любом случае, макросы ограничены функциями, которые можно выразить с помощью всего одного выражения. Да есть еще и другие проблемы с макросами, которые привели к выходу их из моды при программировании на С++. В целом, лучше избегать их использования.

Что работает, а что нет

Как узнать, можно ли реализовать данную шаблонную функцию с тем или иным типом данных? Например, можно ли использовать функцию find() из программы TEMPFIND для нахождения С-строки (типа char*) в массиве таких строк? Чтобы выяснить этот факт, необходимо проверить операторы, используемые в функции. Если они все способны обработать такой тип данных, то, может быть, что-нибудь и получится. В find(), между тем, мы сравниваем две переменные с помощью оператора ==, а его нельзя использовать с такими строками. Но можно обратиться к библиотечной функции strcmp(). Таким образом, работать с С-строка-ми у нас не получилось. Зато наш шаблон функции работает с классом string, потому что в нем перегружен оператор сравнения (--).

Начните с обычной функции

При написании шаблонных функций, наверное, лучше начать с обычной функции, которая работает с фиксированным типом данных. Можно модифицировать и отлаживать ее сколько душе угодно, совершенно не беспокоясь о синтаксисе шаблонов и разнообразии типов. Затем, когда все доведено до блеска и работает без перебоев, можно ввернуть определение функции в шаблон и проверить, как он будет работать с различными типами.

Шаблоны классов

Шаблонный принцип можно расширить и на классы. В этом случае шаблоны обычно используются, когда класс является хранилищем данных (хороший тому пример мы увидим в следующей главе «Стандартная библиотека шаблонов (STL)»). 648

Глава 14. Шаблоны и исключения

Стеки и связные списки, рассмотренные нами в предыдущих главах, — тоже типичные примеры классов-хранилищ данных. До сих пор все приводимые примеры хранилищ могли содержать данные только одного базового типа. Класс stack из программы STAKARAY (глава 7 «Массивы и строки»), например, мог хранить только значения типа int. Вот немного сокращенная версия этого класса:

class Stack

private: int stEMAX]: 1nt top; public: StackO:

void push(int var); int popO;

}:

//целочисленный массив //Индекс вершины стека

//конструктор //int-аргумент //возвращает значение int

Если бы мы захотели хранить значения типа long, пришлось бы написать абсолютно новое определение класса:

class LongStack

private: long stEMAX]; int top; public: LongStackO: void pushdong var); long popO:

}:

//массив long //Индекс вершины стека

//конструктор //int-аргумент //возвращает значение int

Подобным же образом нам пришлось бы создавать классы для хранения данных каждого типа, если бы не шаблоны классов, которые и тут приходят к нам на помощь. С их помощью можно написать такую спецификацию класса, которая сохранит все, что попросят, без лишних вопросов. Создадим вариацию на тему STAKARAY для демонстрации возможностей шаблонов классов.

Листинг 14.3. Программа TEMPSTAK

// tempstak.cpp

// реализация стека в виде шаблона !include <iostream> using namespace std: const int MAX - 100; /////////////////////////////////////////////////////////// template <class Type> class Stack

private: Type stEMAX]: int top; public; StackO

{ top = -1: } void pushtType var) //занести число в стек { st[++top] - var: }

//стек: массив любого типа //индекс вершины стека

//конструктор Шаблоны классов 649

Туре рор() //вынуть число из стека

{ return st[top--]: }

}:

///////////////////////////////////////////////////////////

int mainO {

Stack<float> si: //si - объект класса Stack<float>
Предыдущая << 1 .. 238 239 240 241 242 243 < 244 > 245 246 247 248 249 250 .. 341 >> Следующая
Реклама
Авторские права © 2009 AdsNet. Все права защищены.
Rambler's Top100