Московский государственный технический университет

им.   Н. Э. Баумана

 

 

 

 

 

 

Утверждаю:

 

___________________

 

«___»__________2005 г.

___________________

 

 

 

 

 

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

по курсу ПППО

 «Наследование, виртуальные функции и абстрактные классы»

           

Вариант №18

 

10

(количество листов)

 

 

 

 

 

 

ИСПОЛНИТЕЛЬ:

студент группы ИУ5-63

Тесленко М.В.

______________

 

 «___»__________2005 г.

 

 

 

МОСКВА 2005

 

 

 

 

1. Цель работы.

 

Целью лабораторной работы является дополнительное изучение оболочки (IDE) системы программирования BC 3.1 C++ , способов наследования классов, использование виртуальных функций, понятий абстрактного класса и виртуального вызова функций. Студенты создают свои классы и исследуют механизмы вызова виртуальных функций. Учатся проектировать собственные классы и отображать результаты на диаграммах классов и объектов.

 

2. Порядок работы.

В процесса лабораторной работы( она рассчитана на 4 часа) необходимо изучить и выполнить:

 

1.     Порядок и особенности работы с оболочкой: использование отладчика и средств просмотра классов;

2.     Выполнить описание четырех собственных классов (Absrt, Deriv1 ,Deriv2 и Deriv3 названия классов нельзя изменять), связанных следующим образом: Absrt - абстрактный класс, наследованный от Object ( из classlib); Deriv1 - наследуется от Absrt, Deriv2 наследуется от Deriv1, Deriv3 наследуется от Deriv1.

3.     Классы Deriv1 ,Deriv2 и Deriv3, не являются абстрактными и имеют, по крайней мере, одну виртуальную функцию, определенную в классе Absrt как чистая виртуальная функция (тело такой функции обозначается так - "=0").

4.     Построить диаграмму наследования классов для ЛР.

5.     Описать объекты классов Absrt, Deriv1 ,Deriv2 и Deriv3(названия фиксированы - a1, d1, d2, d3) и выполнить их инициализацию и инициализацию указателей на эти типы, которые описываются отдельно( pa1, pd1, pd2, pd3);

6.     Построить диаграмму объектов для лабораторной работы.

7.     Выполнить вызовы виртуальных функций всех классов и объектов через имена объектов и указатели, в том числе через указатель на базовый абстрактный класс( pa1) – это виртуальный вызов!!!.

8.     Занести объекты разных типов в один список типа LIST (из classlib см. ЛР 3).

9.     Распечатать списка с помощью цикла, функции printOn и собственной виртуальной функции print , на основе класса LISTITERATOR.

 

3. Перечень ошибок.

При разработке и отладке программы были обнаружены и исправлены различные синтаксические ошибки.

 

 

4. Диаграмма классов.

 

 

Object – абстрактный базовый класс для всех объектов

Функции:

            isA – возвращает ID класса

            isEqual – определяет равен ли объект другому

            printOn – отображает объект

Abstr, Deriv1, Deriv2, Deriv3 - четыре собственных класса (Absrt, Deriv1 ,Deriv2 и Deriv3 названия классов нельзя изменять), связанные следующим образом: Absrt - абстрактный класс, наследованный от Object ( из classlib); Deriv1 - наследуется от Absrt, Deriv2 наследуется от Deriv1, Deriv3 наследуется от Deriv1.

Container – абстрактный класс родитель всех классов, включает все классы способные содержать 0 или более элементов

Collection – абстрактный класс “коллекционных” структур

List – класс списка

Функции:

            add – добавляет элемент

            detach – удаляет объект

            initIterator- создаёт итератор

            flush – удаление всех объектов из списка

ListIterator – итератор списка

Функции

            current – возвращает ссылку на текущий объект

            ++ - увеличивает значение итератора на 1

            restart – перемещает итератор в первую непустую точку списка

 

 

5. Диаграмма объектов.

 


6.
Листинг программы.

Lab_4_1.cpp

/*           abstr.cpp - main program for lab#4

 *                                   Teslenko, IU5-63, var#18

 */

 

 

#include <conio.h>

#include <list.h>

#include "abstr.h"

 

int main ()

{

  clrscr ();

 

 

  print_info();

        Deriv1 d4 ("Deriv4 for test =");

  Deriv1 d1 ("abstr  -> deriv1");           //инициализация объектов классов d1, d2, d3

  Deriv2 d2 ("deriv1 -> deriv2");

  Deriv3 d3 ("deriv1 -> deriv3");

 

                                     //объявление указателей на объекты классов d1, d2, d3

  Deriv1* pd1 = &d1;

  Deriv2* pd2 = &d2;

  Deriv3* pd3 = &d3;

        Deriv1* pd4 = &d4;

  Abstr* pa;                                          //абстрактный указатель

 

  List ListDerive;                                  //объявление списка

 

              cout << "Object.print() :" << endl;    //вывод по имени объекта

  d1.print(cout);

  d2.print(cout);

  d3.print(cout);          

        d4.print(cout);

  d4 = "After Change";

                          //вывод через указатель

              cout << endl << "Pointer->print() :" << endl;

  pd1->print(cout);

  pd2->print(cout);

  pd3->print(cout);

        pd4->print(cout);

 

              //вывод через абстрактный указатель

  cout << endl << "Abstract_pointer->print() :" << endl;

  pa = pd1;

  pa->print(cout);

  pa = pd2;

  pa->print(cout);

  pa = pd3;

  pa->print(cout);

  getch ();       

 

 

                          //заполнение листа 15-ю объектами классов d1, d2, d3

  cout << endl << endl

               << "Filling of 15 strings"

               << endl;

        char a[5]="dList";

  char *strM;

  char *strT;

        strM=(char *)calloc(8,sizeof(char));

        strM=a;

  for(int i=0;i<5;i++) {*(strM+5)='1'; *(strM+6)=48+i; *(strM+7)='\0'; ListDerive.add(*new Deriv1(strM));};

  for(i=0;i<5;i++) {*(strM+5)='2'; *(strM+6)=48+i; *(strM+7)='\0'; ListDerive.add(*new Deriv2(strM));}

  for(i=0;i<5;i++) {*(strM+5)='3'; *(strM+6)=48+i; *(strM+7)='\0'; ListDerive.add(*new Deriv3(strM));}

 

//вывод списка при помощи PrintOn

  cout << "Printing list with printOn():" << endl;

  printOnList (ListDerive);

  getch();

                                     // with print()

  cout << "Printing list with print():" << endl;

  printList (ListDerive);

  getch ();

 

                                     //удаление всех объектов класса Deriv1 and Deriv3 из листа

  cout << endl << "Deleting Deriv1 and Deriv3 objects from list:" << endl;

  ListIterator it (ListDerive);

  it.restart();

  while ((int)it)

  {

              pa = (Abstr*) &it.current();

              it++;

              if (pa -> need_del ())

              {

                          cout << "Deleting object " << pa->get_cp() << endl;

                          ListDerive.detach (*pa, TShouldDelete::Delete);

              }

 

  }

 

  // вывод лста после удаления

  cout << "List after deleting:" << endl;

  printList (ListDerive);

  getch ();

 

 

  return 0;

}

 

 

 

 

 

// вывод листа при помощи printOn()s

void printOnList (List& l)

{

  ListIterator li (l);

 

  cout << "List of my objects: " << endl;

  for_each (li)

  {

              cout << "         ";

              li.current().printOn(cout);

  }

}

 

// вывод листа при помощи print()s

void printList (List& l)

{

  ListIterator li (l);

 

  cout << "List of my objects: " << endl;

  for_each (li)

  {

              cout << '\t';

              ((Abstr*) &li.current())->print(cout);

  }

}

                                     

Lab_4_2.cpp

#include <iostream.h>

 

void print_info()

{

 cout << "          Lab work 4 of PPPO";

 cout << "\nTeslenko Maxim IU5-63 Variant 18 \n" << endl;

}

 

Abstr.h

 

/*            abstr.h - definitions for lab#4

 *                                            Teslenko, IU5-63, var#18

 */

 

/*            abstr.h - definitions for lab#4

 *                                            Teslenko, IU5-63, var#18

 */

 

#include <iostream.h>

#include <object.h>

#include <string.h>

 

#define SIZE                                       20

#define DERIV1_ID                         1

#define DERIV2_ID                         2

#define DERIV3_ID                         3

#define DERIV1_STRING              "Deriv1"

#define DERIV2_STRING              "Deriv2"

#define DERIV3_STRING              "Deriv3"

#define DERIV1_HASH 1

#define DERIV2_HASH 2

#define DERIV3_HASH 3

#define NELEMS                                              5

 

#define for_each(iter) for (iter.restart(); (int) iter; iter++)

 

 

void get (istream& i, char* p, int n, char echar = '\n');

 

 

class Abstr : public Object                                //создание класса Аbstr на основе класса Object

{

private:

                char cp[SIZE];

       

public:

                Abstr (char* s)

                               {if (strlen (s) <= SIZE) strcpy (cp, s);}

                Abstr ()

                               {memset (cp, 0, SIZE);}

                ~Abstr () {}

                virtual void print (ostream &) const = 0;

                const char* get_cp () const {return cp;}

//        Abstr& operator = (char *stroka){if (strlen (stroka) <=SIZE) strcpy(cp, stroka); return *this;};

 

                virtual classType isA() const = 0;

                virtual char _FAR *nameOf() const = 0;

                virtual hashValueType hashValue() const = 0;

                virtual int isEqual(const Object _FAR & ) const = 0;

                virtual void printOn(ostream _FAR & ) const = 0;

                virtual int need_del () = 0;

};

 

 

class Deriv1 : public Abstr                                //класс Deriv1

{

public:

 

                Deriv1 (char *s) : Abstr(s) {}

                Deriv1 () : Abstr () {}

                ~Deriv1 () {}

 

                virtual void print (ostream &o) const

                               {o << "Deriv1: " << get_cp () << endl;}

 

                virtual classType isA() const                                           {return DERIV1_ID;}

                virtual char _FAR *nameOf() const                              {return DERIV1_STRING;}

                virtual hashValueType hashValue() const   {return DERIV1_HASH;}

                virtual int isEqual( const Object _FAR & o) const

                               {return (o.isA() == DERIV1_ID) ?

                                                               (!strcmp (((Deriv1*)this)->get_cp(), ((Deriv1&)o).get_cp())) : 0;}

                virtual void printOn(ostream _FAR & o) const {print(o);}

                virtual int need_del () {return 1;}

};

 

 

class Deriv2 : public Deriv1                                             //класс Deriv2

{

public:

                Deriv2 (char *s) : Deriv1 (s) {}

                Deriv2 () : Deriv1 () {}

 

 

                void print (ostream &o) const

                               {o << "Deriv2: " << get_cp () << endl;}

 

                virtual classType isA() const                                           {return DERIV2_ID;}

                virtual char _FAR *nameOf() const                              {return DERIV2_STRING;}

                virtual hashValueType hashValue() const   {return DERIV2_HASH;}

                virtual int isEqual( const Object _FAR & o) const

                               {return (o.isA() == DERIV2_ID) ?

                                                               (!strcmp (((Deriv2*)this)->get_cp(), ((Deriv2&)o).get_cp())) : 0;}

                void printOn(ostream _FAR & o) const {print(o);}

                int need_del () { return 0; }

};

 

 

class Deriv3 : public Deriv1                                             //класс Deriv3

{

public:

                Deriv3 (char *s) : Deriv1 (s) {}

                Deriv3 () : Deriv1 () {}

 

 

                void print (ostream &o) const

                               {o << "Deriv3: " << get_cp () << endl;}

 

                virtual classType isA() const                                           {return DERIV3_ID;}

                virtual char _FAR *nameOf() const                              {return DERIV3_STRING;}

                virtual hashValueType hashValue() const   {return DERIV3_HASH;}

                virtual int isEqual( const Object _FAR & o) const

                               {return (o.isA() == DERIV3_ID) ?

                                                               (!strcmp (((Deriv3*)this)->get_cp(), ((Deriv3&)o).get_cp())) : 0;}

                void printOn(ostream _FAR & o) const {print(o);}

                int need_del ()      { return 1;             }

};

 

 

void printOnList (List& l);                                                //прототипы используемых функций

void printList (List& l);

void get (istream& i, char* p, int n, char echar);

void print_info ();

 

 


7. Листинг результатов работы.



Hosted by uCoz