Построение Производного Класса
Рассмотрим построение программы, которая имеет дело с людьми, служащими в некоторой фирме. Структура данных в этой программе может быть например такой:
struct employee { // служащий char* name; // имя short age; // возраст short department; // подразделение int salary; // employee* next; // ... };
Список аналогичных служащих будет связываться через поле next. Теперь давайте определим менеджера:
struct manager { // менеджер employee emp; // запись о менеджере как о служащем employee* group; // подчиненные люди // ... };
Менеджер также является служащим; относящиеся к служащему employee данные хранятся в члене emp объекта manager. Для читающего это человека это, может быть, очевидно, но нет ничего выделяющего член emp для компилятора. Указатель на менеджера (manager*) не является указателем на служащего (employee*), поэтому просто использовать один там, где требуется другой, нельзя. В частности, нельзя поместить менеджера в список служащих, не написав для этого специальную программу. Можно либо применить к manager* явное преобразование типа, либо поместить в список служащих адрес члена emp, но и то и другое мало элегантно и довольно неясно. Корректный подход состоит в том, чтобы установить, что менеджер является служащим с некоторой добавочной информацией:
struct manager : employee { employee* group; // ... };
manager является производным от employee и, обратно, employee есть базовый класс для manager. Класс manager дополнительно к члену group имеет члены класса employee (name, age и т.д.).
Имея определения employee и manager мы можем теперь создать список служащих, некоторые из которых являются менеджерами. Например:
void f() { manager m1, m2; employee e1, e2; employee* elist; elist = m1 // поместить m1, e1, m2 и e2 в elist m1.next = e1 e1.next = m2 m2.next = e2 e2.next = 0; }
Поскольку менеджер является служащим, manager* может использоваться как employee*. Однако служащий необязательно является менеджером, поэтому использовать employee* как manager* нельзя.