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

С++ лабы

.pdf
Скачиваний:
277
Добавлен:
01.02.2019
Размер:
944.72 Кб
Скачать

//Перегрузка оператора "+"

three_d three_d::operator+(three_d op2)

{

three_d temp; temp.x = x + op2.x; temp.y = y + op2.y; temp.z = z + op2.z; return temp;

}

//Перегрузка оператора "="

three_d three_d::operator=(three_d op2)

{

x = op2.x; y = op2.y; z = op2.z;

return *this;

}

//Отображение координат void three_d::show()

{

cout << x << ", "; cout << y << ", "; cout << z << "\n ";

}

int main ()

{

setlocale(LC_ALL, "rus");

three_d a(1, 2, 3), b (10, 10, 10), c; a.show();

b.show();

c = a + b; // сложение объектов a и b c.show();

c = a + b + c; // сложение объектов a, b и с c.show();

c = b = a; // демонстрация множественного присваива-

ния

c.show();

b.show(); _getch(); return 0;

31

}

В приведенном тексте программы обе операторные функции имеют только по одному параметру, несмотря на то, что они перегружают бинарные операции. Это противоречие объясняется тем, что при перегрузке бинарного оператора с использованием функции-члена ей передается явным образом только один аргумент. Второй же неявно передается через указатель this. Таким образом, в строке

temp.x = x + op2.x;

под членом x подразумевается член this->x, т.е. член x связывается с объектом, который вызывает данную операторную функцию. Во всех случаях неявно передается объект, указываемый слева от символа операции, который стал причиной вызова операторной функции. Объект, располагаемый с правой стороны от символа операции, передается этой функции в качестве аргумента.

5.2 Варианты заданий к лабораторной работе

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

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

Основные действия над комплексными числами:

 

a bi c di

a c b d i

;

a bi c di a c b d i ;

a bi c di ac bci adi bdi

2

ac bd bc ad i ;

 

a bi

 

ac bd

bc ad

 

 

 

 

 

 

 

 

 

i .

 

 

c di

c2 d 2

 

 

 

 

 

 

c2

d 2

 

Вариант 2. Определить класс «Дробь» в виде пары. Реализовать методы для сложения, вычитания, умножения и деления дробей. Перегрузить операции сложения, вычитания, умножения, деления, присваивания, отношения для данного класса.

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

32

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

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

Вариант 5. Разработать класс «Полином» от одной переменной. Полином задается степенью и массивом коэффициентов. Реализовать методы для вычисления значения полинома, сложения, вычитания и умножения полиномов. Перегрузить операции сложения, вычитания, умножения, присваивания для данного класса. Полином от одной переменной есть конечная формальная сумма вида:

С0

С x

C x

 

1

 

n

1

n

 

.

Вариант 6. Составить описание класса для определения одномерных массивов (векторов). Предусмотреть возможность обращения к отдельному элементу массива с контролем выхода за пределы массива, возможность задания произвольных границ индексов при создании объекта. Перегрузить операции сложения и вычитания векторов с одинаковыми границами индексов, умножения и деления всех элементов массива на скаляр.

6 НАСЛЕДОВАНИЕ. ВИРТУАЛЬНЫЕ ФУНКЦИИ

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

Задачи:

изучить механизм наследования C++;

изучить виртуальные функции C++;

реализовать программу в соответствии с заданием на лабораторную работу.

6.1 Теоретическая часть 6.1.1 Понятие о наследовании

Наследование – один из трех фундаментальных принципов объ- ектно-ориентированного программирования, поскольку именно благо-

33

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

В стандартной терминологии языка C++ класс, который наследуется, называется базовым. Класс, который наследует базовый класс, называется производным. Производный класс можно использовать в качестве базового для другого производного класса.

Для иллюстрации механизма наследования рассмотрим следущий пример:

class road_vehicle { int wheels;

int passengers; public:

void set_wheels(int num) {wheels = num;} int get_wheels() {return wheels;}

void set_pass(int num) {passsengers = num;} int get_pass() {return passengers;}

};

Это общее определение дорожного транспортного средства можно использовать для определения конкретных типов транспортных средств. Например, в следующем фрагменте путем наследования класса road_vehicle создается класс truck (грузовых автомобилей).

class truck : public road_vehicle { int cargo;

public:

void set_cargo(int size) {cargo = size;} int get_cargo() {return cargo;}

void show(); };

Тот факт, что класс truck наследует класс road_vehicle, означает, что класс truck наследует все содержимое класса road_vehicle. К содержимому класса road_vehicle класс truck добавляет член данных cargo, а также функции-члены, необходимые для поддержки члена cargo.

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

вид:

class имя_производного_класса : доступ имя_базового_класса

{

тело нового класса

34

}

6.1.2 Управление доступом к членам базового класса

Если один класс наследует другой, члены базового класса становятся членами производного. Статус доступа членов базового класса в производном классе определяется спецификатором доступа, используемым для наследования базового класса. Спецификатор доступа базового класса выражается одним из ключевых слов: public, private или protected. Если спецификатор доступа не указан, то по умолчанию используется спецификатор private.

Если базовый класс наследуется как public-класс, его publicчлены становятся public-членами производного класса. Если базовый класс наследуется как private-класс, его public-члены становятся private-членами производного класса. Спецификатор доступа protected объявляет защищенные члены или обеспечивает наследование защищенного класса. Другими словами, спецификатор protected позволяет создать член класса, который буде доступен в рамках данной иерархии классов, но закрыт для остальных элементов программы.

6.1.3 Виртуальные функции

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

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

Рассмотрим пример программы, которая создает базовый класс figure, предназначенный для хранения размеров различных двумерных объектов и вычисления их площадей. Функция set_dim() является стандартной функцией-членом, поскольку эта операция подходит для всех производных классов. Однако, функция show_area() объявлена как виртуальная, так как методы вычисления площади различных объектов

35

будут разными. Программа использует базовый класс figure для выведения двух специальных классов rectangle и triangle.

class figure { protected:

double x, y; public:

void set_dim(double i, double j) { x = i;

y = j;

}

virtual void show_area() {

cout << "Вычисление площади не определено.";

}

};

class triangle : public figure { public:

void show_area() {

cout << "Площадь треугольника: "; cout << x * 0.5 * y;

}

};

class rectangle : public figure { public:

void show_area() {

cout << "Площадь прямоугольника: "; cout << x * y;

}

};

int main ()

{

setlocale(LC_ALL, "rus");

figure *p; //указатель на базовый тип triangle t; //объекты производных типов rectangle r;

p = &t; p->set_dim(10.0, 5.0); p->show_area();

p = &r;

36

p->set_dim(10.0, 5.0); p->show_area(); _getch();

return 0;

}

Из текста программы видно, что при работе с классами rectangle и triangle используется одинаковый интерфейс, несмотря на то, что в них реализованы собственные методы вычисления площади соответствующих объектов.

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

6.2 Варианты заданий к лабораторной работе

Задание 1.

Необходимо построить иерархию классов согласно схеме наследования, приведенной в варианте задания (таблица 6.1). Каждый класс должен содержать инициализирующий конструктор и функцию Show для вывода значений. Функция main должна иллюстрировать иерархию наследования.

Таблица 6.1 – Варианты индивидуальных заданий

 

Номер

Иллюстрация

1

2

1

 

 

 

 

 

 

 

37

Продолжение таблицы 6.1

1

2

2

3

4

38

Продолжение таблицы 6.1

1

2

5

6

Задание 2.

Разработать программу с использованием наследования классов и виртуальных функций согласно вариантам, приведенным в таблице 6.2.

Таблица 6.2 – Варианты индивидуальных заданий

Номер

Задание

Классы:

железнодорожный вагон;

вагон для перевозки автомобилей;

1цистерна.

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

39

Продолжение таблицы 6.2

1

2

 

Классы:

 

точка;

2

линия;

круг.

 

 

Используя виртуальные функции, не зная с объектом какого

 

класса вы работаете, выведите на экран координаты и размер.

 

Классы:

 

работник больницы;

 

медсестра;

3

хирург.

 

Используя виртуальные функции, не зная с объектом какого

 

класса вы работаете, выведите на экран возраст и название

 

должности.

 

Классы:

 

точка;

 

квадрат;

4

пирамида.

 

Используя виртуальные функции, не зная с объектом какого

 

класса вы работаете, выведите на экран его размер и коорди-

 

наты.

 

Классы:

 

реагент;

 

углерод;

5

железо.

Используя виртуальные функции, не зная с объектом какого

 

 

класса вы работаете, выведите на экран его количество и свой-

 

ства (форма кристаллической решетки для углерода и чистота

 

выработки руды для железа).

Классы:

воин;

пехотинец (винтовка);

6матрос (кортик).

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

40

Соседние файлы в предмете Программирование на C++