Бьерн Страуструп - Язык программирования С++. Главы 5-7 - Множественное наследование
ОГЛАВЛЕНИЕ
Страница 40 из 70
6.5 Множественное наследование
В $$1.5.3 и $$6.2.3 уже говорилось, что у класса может быть несколько прямых базовых классов. Это значит, что в описании класса после : может быть указано более одного класса. Рассмотрим задачу моделирования, в которой параллельные действия представлены стандартной библиотекой классов task, а сбор и выдачу информации обеспечивает библиотечный класс displayed. Тогда класс моделируемых объектов (назовем егоsatellite) можно определить так:
class satellite : public task, public displayed {Такое определение обычно называется множественным наследованием. Обратно, существование только одного прямого базового класса называется единственным наследованием.
// ...
};
Ко всем определенным в классе satellite операциям добавляется объединение операций классов task и displayed:
void f(satellite& s)С другой стороны, объект типа satellite можно передавать функциям с параметром типа task или displayed:
{
s.draw(); // displayed::draw()
s.delay(10); // task::delay()
s.xmit(); // satellite::xmit()
}
void highlight(displayed*);Очевидно, реализация этой возможности требует некоторого (простого) трюка от транслятора: нужно функциям с параметрами task и displayed передать разные части объекта типа satellite.
void suspend(task*);
void g(satellite* p)
{
highlight(p); // highlight((displayed*)p)
suspend(p); // suspend((task*)p);
}
Для виртуальных функций, естественно, вызов и так выполнится правильно:
class task {Здесь функции satellite::draw() и satellite::pending() для объекта типа satellite будут вызываться так же, как если бы он был объектом типа displayed или task, соответственно.
// ...
virtual pending() = 0;
};
class displayed {
// ...
virtual void draw() = 0;
};
class satellite : public task, public displayed {
// ...
void pending();
void draw();
};
Отметим, что ориентация только на единственное наследование ограничивает возможности реализации классов displayed, task и satellite. В таком случае класс satellite мог бы быть task или displayed, но не то и другое вместе (если, конечно, task не является производным от displayed или наоборот). В любом случае теряется гибкость.