Объектно-ориентированное программирование - Учебное пособие (А.А. Хусаинов)

Расчетно-графическое задание 1

 

Первичные классы и объекты

 

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

Классы определяются с помощью нижеследующих полей:

Символьная строка состоит из последовательности символов и длины строки.

Трехмерный вектор состоит из тройки вещественных чисел.

Многочлен от одной переменной задается массивом вещественных коэффициентов и степенью n многочлена.

Рациональное число определяется как пара целых чисел – числитель и знаменатель дроби. Дробь несократима и знаменатель больше нуля.

Неупакованный BCD состоит из массива цифр, знака и длины этого массива.

Битовая строка состоит из массива бит и длины массива. Отрицательные числа представляются аналогично обычным целым числам.

Комплексное число представляется парой вещественных чисел – мнимой и действительной частями комплексного числа.

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

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

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

Комплексное число в полярных координатах представляется парой чисел, первое из которых неотрицательно и задает абсолютную величину, а второе является аргументом arg, лежащим в пределах 0 £ arg < 2p.

Бинарное отношение определяется с помощью квадратной n x n матрицы, состоящей из нулей и единиц и числа n.

 

Варианты заданий

 

1. Символьная строка

 

++

--

int length()

циклический сдвиг вправо,

циклический сдвиг влево,

длина строки

2. Трехмерный вектор

 

*

+

-

double abs()

векторное произведение

сумма векторов

разность векторов

длина вектора

3. Многочлен от одной

   переменной

*

+

-

double cs()

произведение,

сумма,

разность,

свободный коэффициент

4. Прямая в R3,

   проходящая через

   начало координат

*

 

==

прямая, перпендикулярная к прямым

проверка на равенство

5. Бинарное отношение

   n x n

*

+

int sym()

композиция отношений,

объединение,

проверка на симметричность

6. Трехмерный вектор

+

--

[]

float abs()

сумма векторов

разность векторов

координата с данным номером

длина вектора

7. Битовая строка

<, >

==

long abs()

сравнения величин

проверка на равенство

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

8. BCD неупакованный

+, -

*

BCD abs()

сложение и вычитание

умножение

абсолютная величина, возвращается BCD

9. Битовая строка

+

-

BIT abs()

сложение чисел

вычитание чисел

абсолютная величина, возвращается битовая строка

10. Прямоугольное окно

*

+

 

int S()

пересечение,

наименьшее окно, содержащее данные два окна,

площадь окна

11. Рациональное число

+, -

*

RAT abs()

сумма и разность

произведение

модуль, возвращается рациональное число

12. Символьная строка

=

-

+

int length

присваивание,

обращение,

конкатенация,

длина строки

13. Комплексные числа

+,-

*, /

float abs()

float arg()

сумма и разность

произведение и частное

 модуль,

 аргумент

14. Рациональное число

*, <, >,

==

float abs()

умножение и сравнения

сравнение на равенство

значение

15. Трехмерные вектора

+,-

*

float abs()

сумма и разность,

векторное произведение

длина вектора

16. Плоскость в R3

*

 

==

перпендикулярная плоскость к

двум плоскостям,

проверка на равенство

17. Символьная строка

 

=

<=, >=

 

присваивание

сравнение относительно лексико-графического отношения порядка

18. Трехмерные векторы

*

+,-,

float abs()

скалярное произведение,

сумма, разность

длина

19. Бинарное отношение

   n x n

<=

*

int trans()

включение

строгое включение

композиция

проверка на транзитивность

20. Трехмерный вектор

 

+

-

float abs()

Vol(a,b,c)

сложение векторов

вычитание

длина вектора

смешанное произведение

21. Символьная строка

 

==

=

<=

int length()

проверка на равенство,

присваивание,

подстрока,

длина строки

22. Бинарное отношение

 

*

-

<=

int antisym()

пересечение,

обращение (унарная операция)

включение,

проверка на антисимметричность

23. Битовая строка

+, -

++, --

сложение и вычитание

прибавить или вычесть единицу

 

24. Комплексные числа в полярных координатах

+, -

*

float Re()

float Im()

сумма и разность

произведение

вещественная часть

мнимая часть

25. Битовая строка

&, |, !

double value()

поразрядные логические операции,

значение

26. Битовая строка

>> 

<< 

[]

double value()

сдвиг вправо,

сдвиг влево,

значение бита с заданным номером

27. Вектор n-мерный

*

+, -

float abs()

скалярное произведение,

сумма и разность

длина вектора

28. Матрица n x n

+, -

*

float norma()

сумма и разность

произведение матриц

норма

29. Битовая строка

+

-

double value()

сумма

минус унарный

30. BCD неупакованный

+, - , /

double abs()

сложение, вычитание и деление

значение

 

 

Примеры выполнения РГЗ 1

 

Пример 1

 

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

  

Матрица n x n 

+, -

*

float norma()

сумма и разность

произведение матриц

норма

 

Рассмотрим программу с использованием некоторых рассмотренных классов ввода/вывода в сочетании с собственным классом Matrix, в котором собраны матрица и порядок этой матрицы. Элементы-члены в свою очередь являются закрытыми данными класса.

В этой программе мы рассмотрим ввод/вывод объектов собственного класса с использованием классов istream и ostream, функции которых будут определены дружественными для нашего класса. Это достигается перегрузкой операторов функций >> (для объекта cin класса istream) и << (для объекта cout класса ostream), чтобы они поддерживали работу с нашим созданным классом. Помимо этого в программе будут рассмотрены перегрузки таких операторов, как присваивание (=), сложение (+), вычитание (-) и умножение (*). Причем сложение, вычитание и умножение перегружаются дружественными функциями для класса Matrix, а присваивание – функцией-членом нашего класса Matrix, т.к. для этой операции компилятор С++ предусматривает скрытую функцию по умолчанию, если она не определена в явном виде. Еще в нашем классе рассмотрена функция-элемент norma(), которая возвращает норму матрицы типа float, т.е. третью норму матрицы: третья норма матрицы .

Кроме того, в программе предусмотрены два вида конструкторов: конструктор копирования и, следовательно, конструктор по умолчанию; и соответственно для удаления объекта из памяти без завершения программы предусмотрен деструктор.

 

Примечание. Для ввода и вывода объектов класса Matrix использованы только объекты классов istream и ostream: cin и cout. Функции printf() и scanf() в программе не используются.

 

Программа

 

#include <iostream.h>

#include <conio.h>

#include <math.h>

 

int y;

 

// Класс матрица

class Matrix

   {

   private:

   // Собственные элементы:

 

               static int size;     // Порядок матрицы

               int **matrix;                            // Матрица

   public:

   // Общедоступные элементы:

 

               Matrix() {}      // Конструктор по умолчанию

               Matrix(const Matrix &Object); // Конструктор копирования

               ~Matrix();        // Деструктор

 

               float norma();  // Норма матрицы

               Matrix &operator=(const Matrix &Object); // Перегрузка =

 

               Matrix operator+(Matrix &);   // Сложение матриц

               Matrix operator-(Matrix &);    // Вычитание матриц

               Matrix operator*(Matrix &);   // Перемножение матриц

 

               // Перегрузка оператора << для вывода матрицы

               friend ostream &operator<<(ostream &, Matrix &);

               // Перегрузка оператора >> для ввода матрицы

               friend istream &operator>>(istream &, Matrix &);

   };

 

// Конструктор копирования

Matrix::Matrix(const Matrix &Object)

   {

   int i,j;

   size = Object.size;

   matrix = new int *[size];

   for (i = 0; i < size; i++)

               matrix[i] = new int [size];

   for (i = 0; i < size; i++)

               for (j = 0; j < size; j++)

   matrix[i][j] = Object.matrix[i][j];

   }

 

// Деструктор

Matrix::~Matrix()

   {

   for (int i = 0; i < size; i++)

               delete matrix[i];

   delete matrix;

   }

 

// Норма матрицы

float Matrix::norma()

   {

   int i,j;

   float tmp = 0;

   for (i = 0; i < size; i++)

               for (j = 0; j < size; j++)

                           tmp += matrix[i][j] * matrix[i][j];

   return sqrt(tmp);

   }

 

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

Matrix& Matrix::operator=(const Matrix &Object)

   {

   int i, j;

   size = Object.size;

   matrix = new int *[size];

   for (i = 0; i < size; i++)

               matrix[i] = new int [size];

   for (i = 0; i < size; i++)

               for (j = 0; j < size; j++)

   matrix[i][j] = Object.matrix[i][j];

   return *this;

   }

 

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

Matrix Matrix::operator+(Matrix &fp1)

   {

   int i, j;

   if (size == fp1.size)

               {

               Matrix fp(fp1);

               for (i=0;i<fp.size;i++)

                           for (j=0;j<fp.size;j++)

                                       fp.matrix[i][j]=matrix[i][j]+fp1.matrix[i][j];

               return fp;

               }

   }

 

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

Matrix Matrix::operator-(Matrix &fp1)

   {

   int i, j;

   if (size == fp1.size)

               {

               Matrix fp(fp1);

               for (i = 0; i < fp.size; i++)

                           for (j = 0; j < fp.size; j++)

                                       fp.matrix[i][j] = matrix[i][j] - fp1.matrix[i][j];

               return fp;

               }

   }

 

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

Matrix Matrix::operator*(Matrix &fp1)

   {

   int i, j, k, sum;

   if (size == fp1.size)

               {

               Matrix fp(fp1);

               for(i = 0; i < fp.size; i++)

                           for(j = 0; j < fp.size; j++)

                                       {

                                       sum = 0;

                                       for (k = 0; k < fp.size; k++)

                                                   sum += matrix[i][k] * fp1.matrix[k][j];

                                       fp.matrix[i][j]=sum;

                                       }

               return fp;

               }

   }

 

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

istream &operator>>(istream &fi, Matrix &fp)

   {

   int i, j;

   fp.matrix = new int *[fp.size];

   for (i = 0; i < fp.size; i++)

               fp.matrix[i] = new int [fp.size];

 

   for (i = 0; i < fp.size; i++)

               for (j = 0; j < fp.size; j++)

               {

               gotoxy((j + 1) * 4, y + i + 2);

               fi >> fp.matrix[i][j];

               }

   y += i + 2 /*- 1*/;

   return fi;

   }

 

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

ostream &operator<<(ostream &fo, Matrix &fp)

   {

<