лаб4 отчет НМ (Лабораторная работа №4)
Описание файла
Файл "лаб4 отчет НМ" внутри архива находится в следующих папках: Лабораторная работа №4, 4. Документ из архива "Лабораторная работа №4", который расположен в категории "". Всё это находится в предмете "объектно-ориентированное программирование (ооп)" из 3 семестр, которые можно найти в файловом архиве МГТУ им. Н.Э.Баумана. Не смотря на прямую связь этого архива с МГТУ им. Н.Э.Баумана, его также можно найти и в других разделах. Архив можно найти в разделе "лабораторные работы", в предмете "объектно-ориентированное программирование (ооп)" в общих файлах.
Онлайн просмотр документа "лаб4 отчет НМ"
Текст из документа "лаб4 отчет НМ"
Московский Государственный Технический Университет им. Н. Э. Баумана |
Лабораторная работа №4 по курсу Объектно-Ориентированное Программирование «Наследование, виртуальные функции и абстрактные классы» |
Выполнил: Студент группы ИУ5-34 Белоус К.С. _____________________ Принял: Гапанюк Ю.Е. _____________________ |
Москва 2009 |
Цель работы
Целью лабораторной работы является детальное изучение оболочки (IDE) системы программирования BC 3.1 C++ , способов наследования классов, использование виртуальных функций, понятий абстрактного класса и виртуального вызова функций. Студенты создают свои простые классы и исследуют механизмы вызова виртуальных функций. Учатся проектировать собственные классы и отображать результаты на диаграммах классов и объектов.
Действия и операции, необходимые к выполнению
Обязательные требования:
-
Описание четырех классов( Absrt, Deriv1 ,Deriv2 и Deriv3), требования к которым описаны выше (см. 1-й пункт вариантов).
-
В классе Absrt определяется свойство, задаваемое вариантом (см. 2-й пункт вариантов).
-
В классах должна быть определена и переопределена собственная виртуальная функция print, для печати переменной и названия класса объекта.
Примечание: Имена объектов, функций и указателей должны быть такими, как предписано в тексте требований.
-
Описать объекты классов Absrt, Deriv1 ,Deriv2 и Deriv3( a1, d1, d2, d3) и их инициализация и указатели на эти типы( pa1, pd1, pd2, pd3);
-
Выполнить вызов функции print для имен объектов (d1, d2, d3).
-
Задаются значения указателей на созданные объекты ( pd1, pd2, pd3) и выполняется вызов функции print посредством этих указателей.
-
Задается значение pa1 (указатель на абстрактный класс Absrt) как указатель на d1 и вызывается функции print через этот указатель. Задается значение pa1 как указатель на d2 и вызывается функции print через этот указатель. Задается значение pa1 как указатель на d3 и вызывается функции print через этот указатель (это виртуальный вызов !!).
-
Описать объект типа список LIST ListDerive.
-
Тремя циклами в список ( add) последовательно заполнить по пять объектов каждого из типов Deriv1 ,Deriv2 и Deriv3. Объекты порождаются оператором new. Все объекты должны быть различимы (в цикле нужно изменять параметры объектов).
-
Выполнить распечатку списка с помощью одного цикла (с использованием класса LISTITERATOR см. 3ЛР) и стандартной функции printOn, перегруженной в классах Deriv1 ,Deriv2 и Deriv3( методы current, restart, int).
-
Построить диаграмму объектов для данного момента выполнения программы.
-
Выполнить распечатку списка с помощью одного цикла (с использованием класса LISTITERATOR см. 3ЛР) и функции print, перегруженной в классах Deriv1 ,Deriv2 и Deriv3 (используя методы current, restart, int) и вычисляемого указателя на базовый класс (pa1). Для примера формирования ссылки: (( Absrt*) &AI.current())->print();
-
Выполнить удаление элементов из общего списка по вариантам (см. 3-й пункт вариантов).
-
Повторно распечатать список после удаления.
Дополнительные требования (выполняются по желанию сильными студентами):
-
Все тоже с классами DOUBLELIST и DOUBLELISTITERATOR;
-
Продемонстрировать использование виртуального класса на примере.
Перечень ошибок
1. Синтаксические ошибки.
2. Ошибки в цикле удаления объектов из списка (проблемы с инкрементацией итератора).
Диаграмма классов.
ios – сохраняет информацию о потоке, содержит операторы для форматирования.
ostream – содержит перегрузку операции <<.
istream – содержит перегрузку операции >>.
iostream – обобщенный класс классов ostream и istream.
streambuf – обеспечивает операции ввода/вывода на низком уровне (взаимодействие с устройствами).
ostream_withassign, istream_withassign, iostream_withassign – содержат перегрузку операций =.
TShouldDelete – абстрактный класс, предоставляющий интерфейс для контейнеров, в котором определена операция удаления элемента.
Collection – содержит описание функции добавление элемента в массив, поиск элемента в массиве.
Container – содержит функции печати массива и др.
ListElement – является родителем всего, что мы захотим хранить в нашей структуре данных.
ContainerIterator – определяет функции иерархического прохождения через объекты.
ListIterator – итератор списка.
DobleList – класс двунаправленного списка.
DoubleListIterator – класс итераторов двунаправленного списка.
isA – возвращает ID класса.
isEqual – определяет равен ли объект другому.
printOn – отображает объект.
Abstr, Deriv1, Deriv2, Deriv3 - четыре собственных класса (Absrt, Deriv1, Deriv2 и Deriv3 названия классов нельзя изменять), связанные следующим образом: Absrt - абстрактный класс, наследованный от Object (из classlib); Deriv1 - наследуется от Absrt, Deriv2 наследуется от Deriv1, Deriv3 наследуется от Deriv1.
Диаграмма объектов программы
Листинг программы
Файл lab4.cpp
#include <iostream.h>
#include <object.h>
#include <list.h>
#include <dbllist.h>
#include <conio.h>
void about();
class Abstr: public Object
{
private:
float val;
public:
Abstr (float fl=0) {val=fl;}
virtual void print(ostream& )const = 0;
virtual int isToDel() const = 0;
virtual char _FAR *nameOf() const = 0;
virtual classType isA() const = 0;
virtual hashValueType hashValue() const = 0;
virtual int isEqual( const Object _FAR & ) const = 0;
virtual void printOn( ostream _FAR & ) const = 0;
float get_val() const {return(val);}
};
class Deriv1: public Abstr
{
public:
Deriv1 (float fl=0): Abstr(fl) {}
virtual void print(ostream& out) const {out << nameOf() << ": " << get_val();}// << "\n";}
virtual int isToDel() const {return 0;};
virtual char _FAR *nameOf() const {return "Deriv1";}
virtual classType isA() const {return 1;};
virtual hashValueType hashValue() const {return 1;};
virtual void printOn( ostream _FAR & out) const {print(out);};
virtual int isEqual( const Object _FAR & obj) const
{
if (isA()==obj.isA())
{
Deriv1& test = (Deriv1&) obj;
if (test.get_val()==get_val()) return 1; else return 0;
}
return 0;
};
};
class Deriv2: public Deriv1
{
public:
Deriv2(float fl=0): Deriv1(fl) {}
virtual int isToDel() const {return 1;};
virtual char* nameOf() const{return "Deriv2";}
virtual classType isA() const {return 2;};
virtual hashValueType hashValue() const {return 3;};
virtual int isEqual( const Object _FAR & obj) const
{
if (isA()==obj.isA())
{
Deriv2& test = (Deriv2&) obj;
if (test.get_val()==get_val()) return 1; else return 0;
}
return 0;
};
};
class Deriv3: public Deriv1
{
public:
Deriv3(float fl=0): Deriv1(fl) {}
virtual int isToDel() const {return 1;};
virtual char* nameOf() const {return "Deriv3";}
virtual classType isA() const {return 3;};
virtual hashValueType hashValue()const {return 3;};
virtual int isEqual( const Object _FAR & obj) const
{
if (isA()==obj.isA())
{
Deriv3& test = (Deriv3&) obj;
if (test.get_val()==get_val()) return 1; else return 0;
}
return 0;
};
};
void main()
{ about();
//Abstr a1;
Deriv1 d1(23.1);
Deriv2 d2(2.0);
Deriv3 d3;
Abstr* pa1;
Deriv1* pd1;
Deriv2* pd2;
Deriv3* pd3;
cout << " Print (object): \n";
d1.print(cout << "\n");
d2.print(cout << "\n");
d3.print(cout << "\n");
cout << "\n Print (pointer): \n";
pd1=new Deriv1(d1);
pd2=new Deriv2(d2);
pd3=new Deriv3(d3);
pd1->print(cout << "\n");
pd2->print(cout << "\n");
pd3->print(cout << "\n");
cout << "\n Print (abstract class): \n";
pa1=new Deriv1(d1);
pa1->print(cout << "\n");
pa1=new Deriv2(d2);
pa1->print(cout << "\n");
pa1=new Deriv3(d3);
pa1->print(cout << "\n");
List ListDerive;
// Zapolnenie spiska
int i;
cout.precision(2);
for(i=0; i<5; i++) {ListDerive.add(*new Deriv1(i+10.11));}
for(i=0; i<5; i++) {ListDerive.add(*new Deriv2(i+20.22));}
for(i=0; i<5; i++) {ListDerive.add(*new Deriv3(i+30.33));}
// PrintList
getch();
cout << "\n\n Pechat' elementov iz spiska (ListIterator & printOn): " ;
ListIterator iter(ListDerive);
while (iter.current()!=NOOBJECT)
{
iter.current().printOn(cout << "\n");
iter++;
}
getch();
cout << "\n\n Pechat' elementov iz spiska (printOn): \n" ;
iter.restart();
while (iter.current()!=NOOBJECT)
{
(( Abstr*) &iter.current() )->print(cout << "\n");
iter++;
}
getch();
cout << "\n\n Deleting Derive2 & Derive3 objects: \n";
iter.restart();
while (iter.current()!=NOOBJECT)
{
pa1=(Abstr*) &iter.current();
iter++;
if (pa1->isToDel())
{
pa1->print(cout << "\nDeleting: ");
ListDerive.detach(*pa1, TShouldDelete :: Delete);
}
}
ListDerive.printOn(cout << "\n\n ListDerive after Deleting: \n");
getch();
////Dop
clrscr();
DoubleList DoubleListDerive;
// Zapolnenie dbl_spiska
cout.precision(2);
for(i=0; i<5; i++) {DoubleListDerive.add(*new Deriv1(i+10.11));}
for(i=0; i<5; i++) {DoubleListDerive.add(*new Deriv2(i+20.22));}
for(i=0; i<5; i++) {DoubleListDerive.add(*new Deriv3(i+30.33));}
// PrinDoubletList
getch();
cout << "\n\n Pechat' elementov iz dbl_spiska (DoubleListIterator & printOn): " ;
DoubleListIterator db_iter(DoubleListDerive);
DoubleListDerive.initIterator();
while (db_iter.current()!=DoubleListDerive.peekAtTail())