Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

628_Nechta_I.V._Osnovy_ob`ektno-orientirovannogo_

.pdf
Скачиваний:
8
Добавлен:
12.11.2022
Размер:
333.92 Кб
Скачать

КОНТРОЛЬНЫЕ ВОПРОСЫ

Приведите примеры ситуаций, в которых необходимо применять ограничение области видимости элементов класса?

Какой режим доступа к полям класса устанавливается по умолчанию?

Лабораторная работа №4.

Принцип наследования. Создание иерархии классов

ЦЕЛЬ РАБОТЫ: Изучение принципа наследования и возможностей его применения.

ОСНОВНЫЕ СВЕДЕНИЯ

Основным достоинством объектно-ориентированного программирования является возможность повторного использования ранее созданных классов через наследование. Наследование – создание иерархии классов для того, чтобы поля данных и методы предков автоматически становились полями данных и методами потомков. Наследование реализуется возможностью объединять класс с другим, во время объявления второго класса. Рассмотрим следующую иерархию объектов, представленную на рис. 5.

 

 

 

 

 

Животное

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Млекопитающее

 

 

 

 

Птица

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Мышь

 

Собака

 

 

Голубь

 

 

Птеродактиль

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Рис. 5. Иерархия объектов программы «Животные»

Класс, лежащий на вершине иерархии, содержит поля характерные для всех классов иерархии, например, вес. По мере углубления вниз иерархии производится добавление отдельных полей характерных только для данного вида существ (например, поле Размах крыла для класса Птица), причем остальные поля автоматически наследуются из родительского класса. Такой механизм очень удобен в использовании и позволяет быстро разрабатывать большое количество объектов разных типов. Пример:

class Animal{ public: int weight;

11

};

class Bird : public Animal{ public:

int wingspan;

};

Таким образом, класс Bird имеет не только свое поле wingspan, но и унаследованное weight.

ЗАДАНИЕ

Задание 1. В программе из лабораторной работы 3 создать иерархию графических классов, согласно рис. 6. Описания классов оформить в отдельном модуле.

Графическая фигура

точка

отрезок окружность

прямоугольник

 

ромб

 

треугольник

 

эллипс

 

 

 

 

 

 

 

Рис. 6. Иерархия объектов программы «Графические примитивы»

КОНТРОЛЬНЫЕ ВОПРОСЫ

Объясните что такое наследование?

Можно ли унаследовать свойства сразу же от двух классов?

Лабораторная работа №5.

Принцип полиморфизма. Использование виртуальных методов

ЦЕЛЬ РАБОТЫ: Изучение принципов полиморфизма и возможностей его применения.

12

ОСНОВНЫЕ СВЕДЕНИЯ

Полиморфизм – возможность объектов иметь разную реализацию при одинаковых интерфейсах. Когда наследуются классы, то часть идентификаторов (например, имен методов) оказывается уже использованными, что заставляет программиста придумывать другие имена для схожих по «смыслу» методов. Например:

class technic{ public: int move(){

printf(“Передвигаемся”);

}

};

class tank: public technic{ public:

int move(){

printf(“Едем в танке”);

}

};

class plane: public technic{ public:

int move(){

printf(“Летим на самолете”);

}

};

void main(){ technic a; tank b; plane c;

a.move();

// Передвигаемся

b.move();

// Едем в танке

c.move();

// Летим на самолете

}

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

void main(){

technic a[2];

13

a[0]= new (technic); a[1]= new (tank); a[2]= new (plane);

for (int i=0;i<=2;i++) a[i].move();

Результат:

Передвигаемся Едем в танке Летим на самолете

ЗАДАНИЕ

Создать массивы фигур из иерархии (см. лаб.раб. № 4). Нарисовать фигуры. Добавить методы движения фигур:

a)прямолинейное движение с отражением от стенок экрана;

b)вращение вокруг центра фигуры.

Создать массив динамических объектов (из ранее созданной иерархии графических классов). Нарисовать движущиеся фигуры. Массив должен быть один, а фигуры - различные. При описании методов движения и рисования фигур использовать виртуальные методы.

КОНТРОЛЬНЫЕ ВОПРОСЫ

Объясните что такое полиморфизм?

Когда используются виртуальные функции?

Лабораторная работа №6. Использование динамических объектов

ЦЕЛЬ РАБОТЫ: Получить навык преобразования кода программы для повышения удобочитаемости кода программы.

ОСНОВНЫЕ СВЕДЕНИЯ

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

14

Идентификаторы должны быть содержательными (по имени можно сказать о назначении объекта):

Имена переменных должны быть существительными. Если они состоят из нескольких слов, то такие слова должны разделяться символом подчеркивания (num_students), либо каждое слово должно начинаться с заглавной буквы (FileSize).

Имена функций должны быть глаголами. (OpenFile). Следует избегать аббревиатур.

Имена типов следует писать слитно, не разделяя слова. Каждое слово необходимо начинать с большой буквы(StrongTank). Для разделения классов,

объединений

и

констант

часто

используются

префиксы.

const kPi=3.14;

 

 

 

 

 

Описание классов следует форматировать следующим образом.

class Student{ public:

char name[9]; int age; Sudent() {

age=0;

}

}

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

Рефакторинг кода – процесс изменения кода программы с целью увеличения его удобочитаемости и облегчения дальнейшей его модификации. Рефакторинг применяется при наличии избыточного числа временных переменных, «длинной» реализации метода класса, «длинного» списка параметров функции, «длинного» класса и т.д. Кроме этого для повышения удобочитаемости применяется форматирование кода программы.

ЗАДАНИЕ

Описать класс tlist, инкапсулирующий основные свойства линейного списка. В качестве методов класса должны быть описаны необходимые операции со списками (стеком и очередью). Создать иерархию: список – стек – очередь. Продемонстрировать возможности классов иерархии в основной программе. Текст программы должен быть оформлен по вышеописанным правилам.

15

Лабораторная работа №7. Разработка класса STRING

ЦЕЛЬ РАБОТЫ: Научиться пользоваться механизмом перегрузки операторов.

ОСНОВНЫЕ СВЕДЕНИЯ

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

Практически все операторы С++ могут быть перегружены, кроме указанных ниже:

Оператор

Назначение

.

Доступ к полям объекта

.*

Указатель на элемент

::

Доступ к области видимости

?:

Условный оператор сравнения

Табл. 2. Не перегружаемые операторы С++

Для перегрузки оператора используется следующая запись. class my{

public: int x;

int operator +(int a){ return this→x+a;

}

int operator +(my A) return this→x+A.x;

};

my N,M; M.x=5; N.x=6;

int b=M+7; //второй параметр число 7, результат b=12 b=M+N; // второй параметр объект N, результат b=11

Первым параметром считается сам объект после которого стоит оператор (в нашем случае M). В данном примере оператор суммы перегружен для класса my как левого операнда, вторым параметром (правым операндом) может идти число типа int или объект класса my.

Для обращению к полям первого параметра используется указатель this. Следовательно, запись

int b = 7+M;

16

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

operator int(){ return this→x;

}

После этого компилятор сможет преобразовать объект класса в целочисленный тип ( например, b=(int) M )или осуществлять автоматическое преобразование по необходимости. Здесь число 7 типа int, соответственно компилятор попытается конвертировать его автоматически в тот же тип. При перегрузке оператора «=» возвращаемое значение должно передаваться по ссылке. Как правило, возвращается сам объект.

class my{ public:

int x;

my & operator =(int a){ this→x=a; return *this;

}

};

my M;

M=5; //M.x=5;

Здесь оператору подается на вход число int a, затем производится присваивание полю х объекта M нового значения. В итоге возвращается сам объект.

Операторы приведения типа также могут быть перегружены.

class my{

operator int(my &A){ return A.

}

ЗАДАНИЕ

Написать класс String содержащий строку. Перегрузите необходимые операторы, чтобы работа с объектами данного класса была аналогичной с типом string языка Pascal. (Например, конкатенация строк s=s1+s2, доступ к символу s[i]=’1’, присваивание констант s=”hello”, приведение типа printf(“%s”,(char)s), сдвиг букв строки на одну позицию s<<1).

17

КОНТРОЛЬНЫЕ ВОПРОСЫ

Можно ли при перегрузке присваивания создать новый объект и его возвратить?

Как перегрузить оператор ++ в постфиксной и префиксной записи?

Лабораторная работа №8. Шаблоны

ЦЕЛЬ РАБОТЫ: Научиться пользоваться механизмом шаблонов.

ОСНОВНЫЕ СВЕДЕНИЯ

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

int abs(int x){ return (x>0)?x:-x;

}

float abs(float x){ return (x>0)?x:-x;

}

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

template <class T> T abs(T x){ return (x>0)?x:-x;

}

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

ЗАДАНИЕ

Написать функцию сортировки массива произвольной длинны с объектами произвольного типа (int, float, double, my, string). Классы my и string использовать созданные в лабораторной работе № 6. Для сравнения объектов потребуется перегрузка операторов > < ≥ ≤.

КОНТРОЛЬНЫЕ ВОПРОСЫ

Как конкретизировать тип данных при вызове шаблонной функции?

18

Какие проблемы могут возникнуть при автоматическом выборе компилятором типа данных для шаблона?

Лабораторная работа №9. Разработка программы «Магазин».

ЦЕЛЬ РАБОТЫ: Научиться пользоваться механизмом обработки исключительных ситуаций.

ОСНОВНЫЕ СВЕДЕНИЯ

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

try{

//блок возбуждения исключительных ситуаций trow 10; // возбуждение исключения

}

catch (type1 arg){

// блок перехвата исключительных ситуаций

}

После возбуждения исключительной ситуации, она перехватывается соответствующей указанному типу инструкцией catch. Рассмотрим пример:

int test(int i){

if (test) trow i;

}

void main(){ try{

cout <<”начало”; test(1);

test(0);

test(2);

}

catch (int i){

cout << “перехват ”; cout << i;

}

}

Результат: перехват 1 перехват 2

19

Для обработки всех остальных исключительных ситуаций используется инструкция catch(…). Блоки обработки исключительных ситуаций помогают предотвратить аварийное завершение вашей программы.

В целях уменьшения вероятности возникновения ошибки в программе предусмотрен механизм ограничения доступа к полям класса через свойства. Например :

class ttt{ private:

int a; public:

void set_a(int a){ if (a>0){

this->a=a;

}

}

int get_a(){ return a;

}

};

Свойство set_a() устанавливает значение переменной, а get_a(), соответственно, считывает. Рассмотренный механизм доступа позволяет отслеживать правильность присваиваемых значений. Также в момент присваивания можно выполнять ряд действий, например для активации окна приложения (form->active=true;) следует выполнить ряд дополнительных процедур связанных с процессом активации.

ЗАДАНИЕ

Написать приложение «Магазин». Программа должна давать возможность пользователю просматривать перечень продуктов, доступный объем и их стоимость. Необходимо предусмотреть функцию добавления, удаления товара или изменения его стоимости. Любой продукт в магазине должен иметь срок годности. При наличии просроченного товара система должна уведомлять об этом пользователя, указывая список испорченных продуктов. Иерархия классов должна включать в себя сгруппированные виды товаров (овощи, фрукты, мясо-молочные и др. ) Здесь рекомендуется использовать шаблоны функций для обработки данных о товарах разного типа.

20