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

ООП / Лабы / Lab4C

.doc
Скачиваний:
28
Добавлен:
18.02.2017
Размер:
377.34 Кб
Скачать

6

МГИЭТ(ТУ)

Кафедра ВТ

факультет МПиТК

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

«Перегрузка операций в классе»

(компилятор «Borland C++ Builder»)

Составил: ст.пр. Тельминов О.А.

10/2001 г.

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

ЗАДАНИЕ

В работе представлены 3 задачи. Каждому варианту соответствует одна задача (табл.).

Табл. Соответствие задач и вариантов

Вариант

Задача

Вариант

Задача

Вариант

Задача

1

1

10

1

19

1

2

2

11

2

20

2

3

3

12

3

21

3

4

1

13

1

22

1

5

2

14

2

23

2

6

3

15

3

24

3

7

1

16

1

25

1

8

2

17

2

26

2

9

3

18

3

27

3

Необходимо написать, отладить и сдать программу.

– Программа должна обеспечивать добавление/удаление объектов заданного класса (до 10 штук) и отображение их в окне программы;

– Заданный класс должен содержать в себе явно определенные конструктор(ы), деструктор(ы), перегруженные операции (+, –, * и др.) и дополнительные функции. При этом в окне программы должна быть отражена последовательность выполненных над объектом действий (например, вызов деструктора отображается красной точкой рядом с объектом).

– Программа должна обеспечивать интерфейс для сохранения/загрузки рабочего окна программы. При этом в файл записывается информация, необходимая для последующего восстановления из этого файла всей информации об объектах (например, для класса CPoint, объекты которого хранят 2 координаты и цвет, в файл нужно записывать/считывать тройки целых чисел – X Y Color). Для этого в классе необходимо перегрузить операции << и >>.

Задача 1. Работа с объектами класса Строка.

Создайте свой класс Строка для работы со строками.

Создайте три конструктора, в качестве аргумента для которых используйте:

  • указатель на строку char*

  • указатель на объект класса Строка

  • целое число для указания максимальной длины строки, хранимой в объекте.

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

Разместите на форме программы кнопки «Добавить», «Удалить». Пока одна из этих кнопок нажата, на изображении (Image1) можно добавлять/удалять объекты с помощью мыши.

Запрограммируйте выбор одного или нескольких (при нажатой клавише Ctrl) размещенных на Image1 объектов. Выбор объектов уничтожается при щелчке мышью вне области любого из объектов.

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

Создайте еще одну перегруженную функцию +, в качестве аргумента которой используется строка, завершенная ‘\0’ (char*).

Перегрузите 2 операции присваивания = для объекта, в качестве аргумента для которых используйте:

  • указатель на строку char*

  • указатель на объект класса Строка

Создайте в классе Строка функцию Вырезать (начиная с символа № ___ последовательность из ___ символов), удаляющую подстроку. Для вызова разместите на форме необходимые компоненты (кнопку, поля ввода).

Создайте в классе Строка функцию Вставить (начиная с символа № ___ последовательность ___). Для вызова разместите на форме необходимые компоненты (кнопку, поля ввода).

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

Рис. 1. Окно программы, работающей со строковым классом

Задача 2. Класс CComplex для работы с комплексными числами (см. также задачу 1)

Конструкторы, при этом в качестве аргументов могут быть использованы:

  • угол и длина комплексного числа;

  • координаты начала и конца вектора комплексного числа;

  • ссылка на объект этого класса (конструктор копии).

Деструктор.

Обеспечьте выбор одного/нескольких объектов с помощью мыши.

Перегруженные операции + – * / для объектов класса CComplex.

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

Функция, вычисляющая угол между двумя векторами.

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

Задача 3. Класс CMatrix для работы с векторами и матрицами (см. также задачи 1, 2).

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

Перегрузить операции + – *.

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

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

Примечания.

1. Вывод текстовой информации на Canvas объекта (например, Image1) осуществляется функцией Image1->Canvas->TextOut(20, 20, "C++");

2. Для получения указателя на строку (char*) для объекта встроенного класса TString:

Edit1->Text.c_str()

т.е. функция c_str() возвращает указатель на строку (char*) для текста компонента Edit1.

ПОШАГОВАЯ ИНСТРУКЦИЯ ВЫПОЛНЕНИЯ РАБОТЫ

  1. Динамическое создание и удаление объектов.

1.1.Создать свой класс (MyClass) согласно варианту задания в отдельном модуле, предусмотрев в нем:

– Конструктор (Указатель на Image, X, Y). Конструктор инициализирует указатель на изображение, внутренние координаты размещения объекта на изображении. Производит отображение объекта на изображении.

– Деструктор. Стирает изображение объекта на изображении.

– bool IsSelected (int X, int Y). Функция возвращает истину, если указанная точка (X,Y) принадлежит объекту.

– Mark(bool h). Отображает объект в выделенном состоянии (h=true), иначе – в невыделенном.

1.2. Разместить на главную форму приложения Image1, кнопки с заголовками «Добавить» и «Удалить». Для этого рекомендуется использовать кнопки TSpeedButton. Обе созданные кнопки выделить, установить для них общие свойства: GroupIndex=1, AllowAllUp=true. В результате только одна кнопка из двух может быть в нажатом состоянии или обе кнопки отжаты.

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

Описание класса формы TForm1:

private:

MyClass *p[10];

В конструкторе формы присвойте значение NULL каждому из указателей p[i].

При добавлении нового объекта осуществите поиск первого указателя, равного NULL (в цикле).

MouseDown для Image1:

if (SpeedBtn1->Down) // кнопка «Добавить» нажата

{ for (int i=0; i<10; i++)

if (p[i] = = NULL)

{p[i]=new MyClass(Image1, X, Y); break;}

return;}

if (SpeedBtn2->Down) // кнопка «Удалить» нажата

{ for (int i=0; i<10; i++)

if (p[i]) if (p[i].IsSelected(X,Y)) //мышь попала по объекту

{delete p[i]; p[i]=NULL; break;} //после delete важно обнулить указатель!

return;}

В деструкторе формы (onDestroy) произведите очистку всех p[i].

  1. Выделение/сброс выделения объектов

    1. Если объект необходимо выделить, вызовите для него метод p[i]->Mark(true).

    2. В обработчике нажатия MouseDown для Image1 проверьте факт нажатия на Shift – признак группового выделения.

    3. В итоге реализуйте выбор объектов аналогично тому, как это происходит в среде Windows (c учетом Shift).

  1. Реализация перегруженных и дополнительных функций класса.

    1. В соответствии с задачей разместите кнопки и поля ввода для вызова соответствующих функций класса.

    2. Дополните свой класс этими функциями, осуществите связи между кнопками и вызовами функций для выделенного на Image1 объекте (группе объектов). При этом около используемого объекта должен загораться флаг, соответствующий выполненной функции (например, красная точка при вызове конструктора).

  1. Осуществите запись в файл и чтение из файла текущей информации об объектах.

    1. Код для чтения из файла ( с учетом #include <fstream.h>):

void __fastcall TForm1::SpeedButton11Click(TObject *Sender)

{ //сохранить

ofstream oFile;

oFile.open("s.dat");

MyClass object;

if (!oFile) ShowMessage("Save: ERROR!");

else

{

Объект просто помещается в файловый поток

oFile<<object;

}

oFile.close();

}

//---------------------------------------------------------------------------

void __fastcall TForm1::SpeedButton12Click(TObject *Sender)

{ //загрузить

ifstream inFile;

inFile.open("f.dat");//файл с целыми числами

MyClass object;

if (!inFile) ShowMessage("Open: ERROR!");

else

while (1) {inFile>>object; //из файла читается сразу весь объект

if (!inFile) break;

object.Show(); //показать объект

}

inFile.close();

}

//---------------------------------------------------------------------------

    1. Для того, чтобы объекты класса MyClass могли сразу читаться и записываться в поток, необходимо перегрузить операции << и >>:

class MyClass

{

int a, b;

public:

MyClass(int ta=10, int tb=30) {a=ta; b=tb;}

void Show() {ShowMessage(IntToStr(a)+" "+IntToStr(b));}

friend ostream& operator << (ostream& os, const MyClass& obj);

friend istream& operator >> (istream& is, MyClass& obj);

};

ostream& operator << (ostream& os, const MyClass& obj)

В теле записывается последовательность сохранения данных объекта

{ os<< obj.a << " " <<obj.b<< endl;

return os;

}

istream& operator >> (istream& is, MyClass& obj)

В теле записывается последовательность чтения данных объекта

{ is >> obj.a >> obj.b;

return is;

}

Соседние файлы в папке Лабы