Загрузка...

Поля типа и виртуальные функции.


Чтобы использовать производные классы в качестве большем, чем удобное сокращение в объявлении надо решить следующие проблемы:
-при наличии указателя типа base* к чему фактически относится объект производного типа, на котором ссылается указатель.
Есть три пути решения проблемы:
1. Обеспечить что всегда указывается на объекты одного единственного типа.
2. Разместить поле типов в базовом классе для проверки функций
3. Использовать виртуальные функции.
Пример 1: однородные списки
Пример 2,3: неоднородные списки.
Пример к п.2
enum empl_type( M, E);
struct employee {
empl_type type;
employee *next;
char *name;
short department;
//..
};
struct manager : employee {
employee *group;
short level;
//…
};
Имея эти определения можно создать ф-ю, печатающую инфу о каждом служащем .
void print_employee ( employee *e) {
switch ( e->type) {
case E:
cout <<e->name<<”\t”<<e->department<<”\n”;
break;
case M:
cout <<e->name<<”\t”<<e->department<<”\n”;
//…
manager *p=( manager *)e;
cout <<”level”<<p->level<<”\n”;
//…
break;
}}
Эту ф-ю можно использовать для печати списка служащих
void f( employee *ll){
for (;ll;ll->next)
print_employee (ll);
}
Приведенная программа приводит к двум видам ошибок в более крупных программах:
1. ошибки проверки поля типа
2. неудача при размещении всех возможных вариантов, включая switch.

Виртуальные функции.
В.ф. решают проблему с полем типа, позволяя программисту определить функции в базовом классе, которые можно переопределить в производных классах, например:
struct employee {
emplyee *next;
char *name;
short department;
//…
virtual void print();
};
Ключевое слово virtual отмечает, что ф-я printf() может иметь различные версии для различных производных классов. В техничической реализации адреса таких ф-й сохраняется в внутреннюю таблицу, когда оператор вызывает в.ф., С++ ищет адрес нужной ф-ции в этой таблице, тип ф-й объявляется в базовом классе и не может быть переопределен в производном классе.
Виртуальная ф-я должна быть определена для класса, в котором она впервые объявленна, например:
void employee ::print() {
cout <<name<<”\t”<<department<<”\n”;
}
В.ф. следовательно может использоваться даже если нет класса производного от её класса. При порождении класса базовая версия ф-й может использоваться как составная часть «специальной ф-ции». Пример:
struct manager :employee {
employee *group;
short *level;
//…
void print ();
};
void manager ::pritnt() {
employee::print ();
cout <<”\t level”<<level<<”\n”;
//….
}
viod f( employee*ll) {
for (;ll;ll=ll->next)
ll->print();
}

Загрузка...