Программирование >>  Дополнительные возможности наследования 

1 ... 218 219 220 [ 221 ] 222 223 224 ... 265


Листинг 21.3. Испоньзовапие подставиявмоп функции вместе макроса

12 13 14 15 16 17 18 19 20 21 22

#includc <iostreaiii. h>

inline unsigned long Square(unsigriod long a) { return a * a; } inline unsigned long Cubc(unsiQned lonq a)

{ return a * a * a; } int mainO {

unsigned long x-1 ;

for (;:)

cout << Enter a nufnber (0 to quit): ; cin >> x; If (x 0) break;

cout << You enteied: << x;

cout . Square( << x << ): ;

cout Square(x):

cout . Cube( X ): ;

cout << Cube(x) . endl:

return 0;

5 Enter a mimbor (0 to quit): 1

* * You entorod. 1. Squaro(l) 1. Cub!!(1): 1.

Enter a numl)er (0 to qui t): 2

You entered: 2. S(unr(=;(2): 4. Ciil)e(2): 8

Enter a numhui (0 I о quii): 3

You entered: 3. Square(3): 9. Guhe(3): 27.

Enter a number (0 1o quit): 4

You entered. 4. Sqiiare(4): 16. Cubo(4): G-l.

Enter a number (0 to ijui t): b

You entered: 5, Squaie(5): 25. Cubo(b): 125

Enter a number (0 to qui I ): 6

You entered: 6. Squ.iio(6), 36. CubG(G). 216.

Enter a number (0 to quit): 0

В строках 3 и 4 определяются две подставляемые функции; SquareO и Cube(). Поскольку обе функции об7,явлены подставляемыми с помощью ключевого слова inlino, они, как и макросы, будут вставлены в код программы по месту каждого вызова, и никаких временных затрат при выполнении программы, связанных с обращениями к функциям, не возникнет.

Напомним, что подставляемые функции помещаются во время компиляции в программу всюду, где делается обращение к фу1гкции (например, в строке 17). А поскольку реального вызова функции никогда не происходит, отсутствуют и временные затраты, связанные с помещением в стек адреса возврата и параметров функции.



в строке 17 вызывается функция Square, а в строке 19 - функция Cube. И вновь-таки, поскольку эти функции подставляемые, реально строка их вызова после компиляции будут выглядеть следующим образом:

16: cout . SquareC х ): х ♦ х << . Cube ( х ): х ♦ х * х << . endl;

Операции со стрпками

препроцессор предоставляет два специальных оператора для управления строками в макросах. Оператор взятия в кавычки (#) берет в кавычки любую строку, которая следует за ним. Оператор конкатенации (##) объединяет две строки в одну.

Оператор взятия в кавычки

Этот оператор берет в кавычки любые следующие за ним символы вплоть до очередно символа пробела. Следовательно, если написать

#define WRITESTRING(x) cout << #х

И выполнить следующий вызов макроса:

WRITESTRINGdhis is а string);

ТО препроцессор превратит его в такую строку кода:

cout << This is а string ;

Обратите внимание, что строка This is а string заключается в кавычки, что и требуется для объекта cout.

Квнкатвнация

Оператор конкатенации позволяет связывать несколько строк в одну. Новая строка на самом деле представляет собой лексему, которую можно использовать как имя класса, имя переменной, смещение в массиве или другом объекте, где может содержаться ряд символов.

Предположим на мгновение, что у вас есть пять функций с такими именами, как fOnePrint, fTwoPrint, fThreePrint, ffourPrint и fFivePrint. Теперь можно сделать следующее объявление:

#define fPRINT(x) f ## х ## Print

Затем использовать макрос fPRINT(x) с параметром Two, чтобы сгенерировать строку fTwoPrint, и с параметром Three, чтобы сгенерировать строку fThreePrint.

В конце второй недели обучения был разработан класс PartsList. Этот список мог обрабатывать объекты только типа List. Предположим, что этот список зарекомендовал себя хорошей работой и вам захотелось так же хорошо создавать списки животных, автомобилей, компьютеров и т.д.

Один метод решения этой задачи мог бы состоять в создании списков AnimalList, CarList, ComputerList и прочих путем вырезки и вставки кода в нужное место. Однако такой вариант решения быстро превратит вашу жизнь в кошмар, поскольку каждое изменение, вносимое в один список, нужно будет вносить во все другие.



Но, к счастью, существует альтернативное решение - использование макросов и оператора конкатенации. Например, можно определить следующий макрос:

tfdefine Listof(Type) class Type##List \ { \

public: \

Type##List(){ } \ private: \

int itsLength; \ } ;

Суть этого примера состоит в том, чтобы включить в одно определение все необходимые методы и данные. Когда нужно будет создать список животных (AnimalList), достаточно записать

Listof(Animal)

и приведенная выше запись превратится в обьявление класса AnimalList. В процессе применения этого подхода не обходится без некоторых проблем, подробно рассмотренных на занятии 19.

Встроенные макросы

Многие компиляторы используют ряд встроенных макросов, таких как DATE , Т1МЕ , LINE и FILE . Каждое из этих имен окружено двумя символами подчеркивания, чтобы снизить вероятность того, что они войдут в противоречие с именами, использованными в вашей программе.

Когда препроцессор встречает один из этих макросов, он делает соответствующую подстановку. Вместо лексемы DATE ставится текущая дата. Вместо Т1МЕ - текущее время. Лексемы LINE и FILE заменяются номером строки исходного кода и именем файла соответственно. Следует отметить, что эти замены выполняются еще до компиляции. Учьтите, что при выполнении программы вместо лексемы DATE будет стоять не текущая дата, а дата компиляции программы. Встроенные макросы часто используют при отладке.

Макрос assertQ

Во многих компиляторах предусмотрен макрос assert, который возвращает значение TRUE, если его параметр принимает значение TRUE, и выполняет установленные действия, если его параметр принимает значение FALSE. Многие компиляторы в этом случае прерывают выполнение программы, другие же генерируют исключительную ситуацию (см. занятие 20).

Одна из важных особенностей макроса assertO состоит в том, что препроцессор вообще не замещает его никаким кодом, если не определена лексема DEBUG. Это свойство - большое подспорье в период разработки и при передаче заказчику конечного продукта. Быстродействие программы не страдает и размер исполняемой версии не увеличивается в результате использования этого макроса.



1 ... 218 219 220 [ 221 ] 222 223 224 ... 265

© 2006 - 2025 pmbk.ru. Генерация страницы: 0.001
При копировании материалов приветствуются ссылки.
Яндекс.Метрика