Мы поможем в написании ваших работ!



ЗНАЕТЕ ЛИ ВЫ?

Динамическая идентификация типов.

Поиск

Динамическая идентификация типа характерна для языков, в которых поддерживается полиморфизм. В этих языках возможны ситуации, в которых тип объекта на этапе компиляции неизвестен.

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

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

В стандарт языка С++ включены средства RTTI (Run-Time Type Idendification) - динамическая идентификация типов. Информацию о типе объекта получают с помощью оператора typeid, определение которого содержит заголовочный файл  <typeinfo.h>.

Имеется две формы оператора typeid:

typeid (объект)

typeid (имя_типа)

Оператор typeid возвращает ссылку на объект типа type_info.

В классе type_info перегруженные операции == и!= обеспечивают сравнение типов.

Функция name () возвращает указатель на имя типа.

Имеется одно ограничение. Оператор typeid работает корректно только с объектами, у которых определены виртуальные функции. Большинство объектов имеют виртуальные функции, хотя бы потому, что обычно деструктор является виртуальным для устранения потенциальных проблем с производными классами. Когда оператор typeid применяют к неполиморфному классу (в классе нет виртуальной функции), получают указатель или ссылку базового типа.

 

Примеры.

1.

#include<iostream>

#include<typeinfo>

using namespace std;

class Base

{

virtual void f(){};

//…

};

class Derived: public Base

{

//…

};

void main()

{

int i;

Base ob,*p;

Derived ob1;

cout<<typeid(i).name(); //Выводится int

p=&ob1;

cout<<typeid(*p).name(); // Выводится Derived

}

 

2.

//начало см. выше

void WhatType(Base& ob)

{

cout<< typeid(ob).name()<<endl;

}

void main()

{

Base ob;

Derived ob1;

WhatType(ob); //Выводится Base

WhatType(ob1); //Выводится Derived

}

3.

//начало см. выше

void main()

{

Base *p;

Derived ob;

p=&ob;

if(typeid(*p)==typeid(Derived)) cout<<“p указывает на объект типа Derived”;

}

Если при обращении typeid(*p), p=NULL, то возбуждается исключительная ситуация bad_typeid

Порядок выполнения работы.

1. Дополнить иерархию классов лабораторной работы № 1 классами “группа”.

Например, для предметной области ФАКУЛЬТЕТ можно предложить классы “ факультет ”, “ студенческая группа ”, “ кафедра ”. Рекомендуется создать абстрактный класс - “ подразделение ”, который будет предком всех групп и абстрактный класс TObject, находящийся во главе всей иерархии.

2. Написать для класса-группы метод-итератор.

3. Написать процедуру или функцию, которая выполняется для всех объектов, входящих в группу (смотри примеры в приложении).

4. Написать демонстрационную программу, в которой создаются, показываются и разрушаются объекты-группы, а также демонстрируется использование итератора.

Методические указания.

1. Класс-группа должен соответствовать иерархии классов лабораторной работы № 1, т.е. объекты этих классов должны входить в группу. Например, для варианта 1 может быть предложена следующая иерархия классов:

 

                                  Tobject (абстр. класс)

 


Персона (абстр. класс) Подразделение (абстрактная группа)

     
 

 


Студент Преподаватель Кафедра  Студенческая группа

 

                  Завкафедрой                   Факультет

 

 

При этом иерархия объектов будет иметь следующий вид:

 

 

Факультет

 


Студ_ группа_1 Студ_ группа_ N Кафедра_1     Кафедра_ N

             
 
     


Студенты        Студенты  Преподаватели Преподаватели

 

                                                          Завкафедрой  Завкафедрой

 

2. Для включения объектов в группу cледует использовать третий способ (через связанный список структур типа TItem).

3. Пример определения добавленных абстрактных классов:

class TObject

{

public:

virtual void Show()=0;

};

class TDepartment:public TObject // абстрактный класс -группа

{

protected:

char name[20]; // наименование

TPerson* head; // руководитель

TItem* last; // указатель на начало св. списка структур TItem

public:

TDepartment(char*,TPerson*);

TDepardment(TDepartment&);

~ TDepartment();                

char* GetName(); 

TPerson* GetHead();

void SetName(char* NAME);

void SetHead(TPerson* p);

void Insert(TObject* p);   

virtual void Show()=0;                      

};

4. Иерархия объектов создается следующим образом (на примере ФАКУЛЬТЕТА):

а) создается пустой ФАКУЛЬТЕТ,

б) создается пустая КАФЕДРА,

в) создаются ПРЕПОДАВАТЕЛИ и включаются в КАФЕДРУ,

г) КАФЕДРА включается в ФАКУЛЬТЕТ,

д) тоже повторяется для другой кафедры,

 

е) создается пустая СТУДЕНЧЕСКАЯ ГРУППА,

ж) создаются СТУДЕНТЫ и включаются в СТУДЕНЧЕСКУЮ ГРУППУ,

з) СТУДЕНЧЕСКАЯ ГРУППА включается в ФАКУЛЬТЕТ,

и) тоже повторяется для другой студенческой группы.

5. Удаляется ФАКУЛЬТЕТ (при вызове деструктора) в обратном порядке.

6. Метод-итератор определяется в неабстрактных классах-группах на основе выбранных запросов.

Например, для класса TStudentGroup может быть предложен итератор void TStudentGroup::ForEach(PF action, float parametr);

где action - указатель на функцию, которая должна быть выполнена для всех объектов, включенных в группу (в данном случае для всех СТУДЕНТОВ), parametr- передаваемая процедуре дополнительная информация.

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

void MyProc(TObject* p,float rate)

{

if (((TStudent*)p) ->GetGrade()>=rate) cout<<(((TStudent*)p) ->GetName());

}

7. Студент определяет передаваемую итератору функцию на основе запросов, которые должны быть выполнены вызовом итератора. Варианты запросов приведены в приложении.

Содержание отчета.

1. Титульный лист.

2. Постановка задачи.

3. Иерархия классов.

4. Иерархия объектов.

5. Определение классов (добавленных или измененных по сравнению с лабораторной работой № 1).

6. Реализация для одного не абстрактного класса-группы всех методов.

7. Реализация итератора.

8. Реализация передаваемой итератору функции.

9. Листинг демонстрационной программы.

 

2.6 Варианты задания.



Поделиться:


Последнее изменение этой страницы: 2021-11-27; просмотров: 155; Нарушение авторского права страницы; Мы поможем в написании вашей работы!

infopedia.su Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. Обратная связь - 3.135.186.233 (0.006 с.)