Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
тех прог.doc
Скачиваний:
38
Добавлен:
14.11.2019
Размер:
3.59 Mб
Скачать

15.2.Встроенные функции

Функции, определенные внутри структуры или класса (о классах речь пойдет ниже), являются встроенными или inline.

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

Учитывая сказанное, можно рекомендовать делать встроенными короткие функции, которые часто вызываются, что может привести к ускорению работы программы.

Можно явно указывать, что функция является встроенной. Для этого используется ключевое слово inline. Например, внутри структуры Time функцию Set можно объявить в виде:

void Set(int hh, int mm); // Установка времени

Указать на то, чтобы эта функция была встроенной, можно при ее определении вне структуры:

inline void Time::Set(int hh, int mm) // Установка времени

{

h = hh; m = mm;

}

Есть ограничения на операторы, которые могут входить во встроенные функции. Они не должны содержать условный оператор if, операторы цикла. Функции, содержащие такие операторы, будут обычными, несмотря на указание сделать их встроенными, а компилятор выдаст предупреждение.

15.3.Классы. Скрытие данных

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

Программа 42. Класс дат

Разработаем класс для моделирования календарных дат.

// Файл DateCl_1.cpp

class Date{

int d, m, y; // День, месяц и год

public: // Раздел открытых членов

void Init_Date(int dd, int mm, int yy) // Инициализация даты

{ // Реализация функции

d = dd; m = mm; y = yy; // внутри класса

}

void Add_Year(int n); // Добавить к дате n лет

void Print();

};

Метка public разделяет тело класса на две части: закрытую и открытую. Здесь закрытыми членами являются d, m и y. Члены класса, расположенные после public, являются открытыми, они образуют открытый интерфейс класса.

Структура – это класс, все члены которого открыты по умолчанию.

Функции-члены класса определяются так же, как функции-члены структуры:

// Продолжение файла DateCl_1.cpp

#include <iostream.h>

void Date::Print()

{

cout << d << ’.’ << m << ’.’ << y;

}

Включим в состав программы вспомогательную функцию для проверки, является или нет год високосным:

// Продолжение файла DateCl_1.cpp

// leap: возвращает 1, если год year високосный и 0, если нет

int leap(int year)

{

return (year % 4 == 0 && year % 100 != 0) || year % 400 == 0;

}

При реализации функции увеличения даты надо учесть 29 февраля високосного года. Если исходная дата приходится на 29 февраля високосного года, а через n лет год будет невисокосный, то будем считать, что спустя n лет после исходной даты будет 1 марта.

// Продолжение файла DateCl_1.cpp

void Date::Add_Year(int n)

{

if(m == 2 && d == 29 && leap(y + n) != 1){ // Через n лет после

m = 3; // 29 февраля будет

d = 1; // 1 марта невисокосного

} // года

y += n;

}

Функции, не являющиеся членами класса, не могут осуществлять непосредственный доступ к закрытым членам, например,

void backday(Date& td)

{

td.d--; // Ошибка, Date::d является закрытой

}

Ограничение доступа к данным имеет следующие преимущества:

так как данные могут изменяться только функциями-членами, легче локализовать ошибку;

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

Используем класс Date в следующей программе:

// Продолжение файла DateCl_1.cpp

#include <conio.h>

int main()

{

Date Studies; // Переменная типа Date

Studies.Init_Date(1, 9, 2005); // Инициализация переменной

cout << ”Исходная дата: ”; Studies.Print(); cout << endl;

Studies.Add_Year(5); // Увеличение даты на 5 лет

cout << ”Через 5 лет: ”; Studies.Print(); cout << endl;

Date D; // Еще переменная типа Date

D.Init_Date(29, 2, 2000);

cout << ”Интересная дата: ”; D.Print(); cout << endl;

D.Add_Year(6);

cout << ”Через 6 лет: ”; D.Print(); cout << endl;

getch();

return 0;

}

Программа выдаст:

Исходная дата: 1.9.2005

Через 5 лет: 1.9.2010

Интересная дата: 29.2.2000

Через 6 лет: 1.3.2006