Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
lek_2_slaydy.doc
Скачиваний:
0
Добавлен:
17.11.2019
Размер:
449.54 Кб
Скачать

3: #Ifndef time1_h

4: #Define time1_h 1

// Предотвращение нескольких #include

5:

6: class Ttime {

7: private:

8: int month;

9: int day;

10: int year;

11: int hour;

12: int minute;

13: public:

14: void Display(void);

15: void GetTime(int &m, int &d, int &y, int &hr, int &min);

16: void SetTime(int m, int d, int y, int hr, int min);

17: char *GetSTime(void);

18: void ChangeTime(long minutes);

19: };

20:

21: #Endif // _ _time1_h

С троки 3, 4 и 21 предохраняют заголовочный файл TIME1.H от включения его в один модуль более одного раза.

Объявление класса TTime в заголовочном файле позволяет использовать этот класс в других модулях.

В листинге 2.4 приводятся функции-члены класса TTime. Подобная организация классов в заголовочных файлах и программных модулях типична. Следует объявлять один или несколько классов в заголовочном файле, заканчивающемся на .H, и приводить тела функций-членов класса в отдельном файле, заканчивающимся на .CPP.

Для компиляции этого модуля из DOS введите команду bcc -c time1.c. Для компиляции его из интегрированной среды сделайте текущим окно с TIME.CPP, установите TargetExpert в EasyWin и нажмите <ALT+F9>.

Замечание

Модуль TIME.CPP остается все еще неполной программой (в нем хватает функции main()). Вы можете скомпилировать TIME.CPP в объектный файл TIME1.OBJ, но для того, запустить результат на выполнение, вы должны написать еще один модуль, содержащий main(). TIME1.CPP содержит программный код, содержащий реализацию класса TTime. Компоновщик может присоединить этот модуль (возможно, вместе с другими) для создания законченной программы. Поскольку модуль TTime скомпилирован отдельно, его можно скомпоновать с несколькими различными программами. Это делает отдельные модули, подобные TTime, идеальными для сохранения общего программного кода для использования в различных приложениях.

Листинг 2.4. TIME1.CPP (реализация класса TTIME)

1://time1.cpp-реализация класса Ttime

2:

3: #include <iostream.h>

4: #include <stdio.h>

5: #include <dos.h>

6 : #include <string.h>

7: #include “time1.h”

8:

9: //Отображение даты и времени

10: void TTime::Display(void)

11: {

12: char s[30];

13: sprintf(s,“Date:%02d/%02d/%04d Time: %02d:%02d”,

14: month, day, year, hour, minute);

15: cout<< s << “\n”;

16: }

17:

18: // Возвращает текущие данные-//члены дату и время

19: void TTime: :GetTime(int &m, int &d, int &y, int &hr, int &min)

20: {

21: m = month; // Возвращение данных-членов тому, кто вызвал функцию

22: d = day;

23: y = year;

24: hr = hour;

25: min = minute;

26: }

27:

28://Устанавливает данные-члены //дату и время

29: void TTime::SetTime(int m, int d, int y, int hr, int min)

30: {

31: month = m; // Присваивание //аргументов данным-членам

32: day = d;

33: year = y;

34: hour = hr;

35: minute = min;

36: }

37:

38: // Возвращает дату и время //объекта TTime в виде символьной //строки

39: char *Ttime::GetSTime(void)

40: {

41: char buffer[40]; // Побольше пространство

42: char *cp; // Указатель на результат, возвращаемый функцией

43:

// формирование строки с закрытыми данными-//членами month, day, year, hour и minute

44:sprintf(buffer,“Date:%02d/%02d/%04d Time: %02d:%02d\n”,

45: month, day, year, hour, minute );

//копирование буферной строки в новую //строку в динамически выделенной //области памяти

46: cp = strdup(buffer);

// Копирование с наименьшим возможным размером

47: return cp;

48: }

49:

50: //Добавление nminutes (может //быть возможным) к текущему //времени

добавляющая или вычитающая указанное количество минут от даты и времени объекта

51: void TTime::ChangeTime(long nminutes)

52: {

53: struct date ds;

54: struct time ts;

55: long timeinsects;

56:

57: ds.da_year = year;

58: ds.da_mon = month;

59: ds.da_day = day;

60: ts.ti_hour = hour;

61: ts.ti_min = minute;

62: ts.ti_sec = 0;

63: ts.ti_hund = 0;

// преобразование даты и времени объекта класса в ..

//формат длинного целого и обратно

64: timeinsecs=dostounix(&ds,&ts);

65: timeinsecs += (nminutes * 60);

66: unixtodos(timeinsects, &ds, &ts);

67: year = ds.da_year;

68: month = ds.da_mon;

69: day = ds.da_day;

70: hour = ts.ti_hour;

71: minute = ts.ti_min;

72: }

Чтобы скомпилировать APPOINT. CPP в законченную программу, следует объединить все разрозненные модули TIME1. Команды, приведенные в предыдущем параграфе, позволяют сделать это для DOS. Для WINDOWS необходимо из интегрированной среды открыть файл проекта APPOINT1.IDE с помощью команд project\open projectВ проекте указываются основной программный модуль (APPOINT.CPP), отделенный модуль(TIME1.CPP) и целевой модель EasyWin _APPOINT1.EXE. Таким же образом следует указать и прочие отдельные модели. После открытия файла проекта нажмите <Ctrl+F9> для компиляции всех моделей, компоновки получившихся в результате компиляции объектных файлов и запуска на выполнение конечного целевого кода. Если у вас получились ошибки, которые могут быть вызваны компиляцией модуля TIME1 для DOS или не-EasyWin Windows, используйте для компиляции Project|build All. Также установите правильные опции local options для APPOINT1.EXE (щелкните правой кнопкой мыши над целевым именем), установив верные пути для заголовочных и библиотечных каталогов Borland C++.

Листинг 2.5. AP1.CPP (отображение примера календаря встреч)

1: #include <iostream.h>

2: #include <stdio.h>

3: #include “time1.h”

4:

5: main()

6: {

7: TTime ap;

8:

9: ap.SetTime(7, 21, 1996, 8, 30);

// добавление 30 мин к дате и времени в appointment

10: for (int slots = 1; slots <= 17; slots++) {

11: ap.Display();

12: ap.ChangeTime(30);

13: }

14: return 0;

15: }

Когда подобный оператор вызывает функцию-член, С++ передает функции адрес объекта, в данном случае адрес appointment. В нутре функции-члена адрес объекта доступен с помощью специального ключевого слова this. Все функции члены получают указатель this, ссылающийся на объект класса, для которого функция-член была вызвано. В листинге 13.5, в строке 12, функции-члену ChangTime() передаются указатель this, в котором хранится адрес appointment. Подобным образом функции-члены ссылаются в объекте класса, для которых они были вызваны.

Можно использовать this в качестве указателя на объект типа класса. Например, строку 21 в листинге 13.4 можно было написать следующим образом:

m = this ->month;

Изменение закрытых данных-членов

Лучшие способы представления данных часто становятся очевидными на полпути в сумасшедшем рывке к завершению проекта. Как обсуждалось раньше, сохранение даты и временив виде числа секунд начиная с фиксированной даты (обычно, 1 января 1970 года в DOS) более удобно и позволяет использовать другие библиотечные функции, использующие такой же формат хранения даты и времени.

Функция-член ChangeTime() в листинге 2.4 преобразует данные-члены дату и время в длинное целое (timeinsecs), что расходует время и производительность в случае частых вызовов этой функции. Очевидно, это функция упростится, если дата и время уже будет храниться в виде длинного целого.

В листингах 2.6 и 2.7 внесены эти изменения в предоставлении данных в классе TTime.файл TIME2.H и соответствующий ему модуль TIME2.EXE.CPP _не законченные программы. Их необходимо скомпилировать и скомпоновать вместе с еще одним модулем, подобным APPOINT2.CPP, в котором определена функция main(). Чтобы скомпилировать результативную программу для DOS, введите команду bcc appoint2 time2. Запустите получившийся в результате выполняемый файл APPOINT2.EXE, введя его имя. Вы также можете скомпилировать каждый модуль отдельно и скомпоновать их объектные файлы с помощью нескольким команд:

bcc -c appoint2

bcc -c time2

bcc appoint2.obj time2.obj

Таким образом, существует более чем один способ “спустить шкуру с кошки” и скомпилировать программу на С++. Для того чтобы скомпилировать и запустить APPOINT2 из интегрированной среды, откройте файл проекта APPOINT2.IDE и нажмите <Ctrl+F9>, как это вы уже делали с APPOINT1. не забудьте использовать Project|Build all в случае появления ошибок (конечно, вызванных предыдущей компиляцией модуля TIME2 для DOS, что делает объектный код несовместимым с Windows).

Листинг 2.6 TIME2.H ( измененный класс TTime)

1: // time2.h – объявление класса TTime

2:

3: #ifndef __TTIME2_H

4: #ifndef __TTIME2_H 1 //Предотвращение нескольких #include

5:

6: class Ttime {

7: private:

8: long dt; // Дата и время – в секундах от 1 января 1970 года

9: public:

10: void Display(void);

11: void GetTime(int &m, int &d, int &y, int &hr, int &min);

12: void SetTime(int m, int d, int y, int hr, int min);

13: char *GetSTime(void);

14: void ChangeTime(long nminutes);

15: };

16:

17: #endif // _ TIME2_H

Класс TTime в TIME2.H идентичен TTime в TIME1.H за исключением того. Что в объявлении присутствует лишь одно закрытое длинное целое dt. Удалены индивидуальные компоненты month, day, year, hour и minute. Конечно, несмотря, на проведенные изменения, открытые функции-члены те же самые, и нет нужды в изменении операторов, в которых используется класс TTime.

Собственно функции-члены нуждаются в изменении, но, по крайней мере, это работа ограничена известным числом легко идентифицируемых функций. В листинге 2.7 решается эта задача.

Листинг 2.7. TIME2.CPP (реализация измененного класса TTime)

1: // time2.cpp – реализация класса TTime

2:

3: #include <iostream.h>

4: #include <time.h>

5: #include <dos.h>

6: #include <string.h>

7: #include ”time2.h”

8:

9: // Отображение даты и времени

10: void Ttime::Display(void)

11: {

12: cout << ctime( &dt);

13: }

14:

15: // Возвращает текущие данные-члены (дату и время)

16: void TTime::GetTime(int &m, int &d, int &y, int &hr, int &min);

17: {

18: struct data ds;

19: struct time ts;

20:

21: unixtodos(dt, &ds, &ts);

22: y = ds.da_year;

23: m = ds.da_mon;

24: d = ds.da_day;

25: hr = ts.ti_hour;

26: min = ts.ti_min;

27: }

28:

29: // Устанавливать член dt

30: void TTime::SetTime(int m, int d, int y, int hr, int min);

31: {

32: struct data ds;

33: struct time ts;

34:

35: ds.da_year = y;

36: ds.da_mon = m;

37: ds.da_day = d:

38: ts.ti_hour = hr;

39: ts.ti_min = min;

40: ts.ti_sec = 0;

41: ts.ti_hund = 0;

42: dt = dostounix(&ds, &ts);

43: }

44:

45: // Возвращает дату и время в виде строки

46: char *TTime::GetSTime(void)

47: {

48: char *cp = strdup(ctime(&dt));

49: return cp;

50: }

51:

52: //Добавление nminutes (может быть отрицательным) к текущему времени

53: void TTime::ChangeTime(long minutes)

54: {

55: dt += (nminutes * 60);

56: }

Новый модуль существенно улучшен по сравнению со старым и занимает меньше памяти. Теперь, когда дата и время сохраняется в виде длинного целого, в строке12 просто вызывается библиотечная функция ctime() для преобразования даты и времени в строку ASCII. Функции – члены GetTime () и PutTime() стали немного сложнее, чем до этого, поскольку им теперь необходимо преобразовать дату и время в разделении параметры и обратно с помощью библиотечных функций unixtodos() и dostounix(), упоминавшихся ранее.

Функции-члены GetSTime() и ChangeTime() существенно улучшены (строки 45–56). GetSTime() передает результат функции ctime() непосредственно strdup() для возвращения даты и время в виде строки. Но лучше всего преобразовалась ChangeTime(), выродившись простой оператор. Поскольку дата и время теперь хранятся в нужной форме, нет больше необходимости в операторах преобразования из предыдущей версии.

Изменение формата данных для упрощения кода – сберегающий время стиль оптимизации программ. С помощью ООП и классов С++ изменения фундаментальной структуры данных не обязательно потребуют соответствующих изменении операторов, использующих эту информацию. Как показано в листинге 13.8, основная программа в проекте “не помнит” об основных модификациях, сделанных классы TTime.

Новая главная программа, APPOINT2.СPP, идентична APPOINT1.CPP, за исключением строки 3, включающей заголовочный файл TIME2.H вместоTIME1.H. В этом маленьком примере действительные преимущества ООП практически незаметны. Конечно, в программе из 10,000 строк с сотнями объектов TTIME изменении потребуется не больше, чем в этом примере! Инкапсуляция данных и функций в классе локализуют изменения в коде путем запрещения прямого доступа к данным, минимизируя таким образом потенциальное количество модификаций, требующихся после изменения внутреннего предоставления данных.

Листинг 2.8. APPOINT2.CPP (отображение примера календаря встреч)

1: #include <iostream.h>

2: #include <stdio.h>

3: #include “time2.h”

4:

5: mаin()

6: {

7: TTime appointment;

8:

9: appointment.SetTime(7, 21, 1996, 8, 30);

10: for (int slots = 1; slots <= 17; slots++) {

11: appointment.Display();

12: appointment.ChangeTime(30);

13: }

14: return 0;

15: }

Open project

Add item

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]