Таблица 1 - Распространение спецификаторов доступа в рамках иерархии наследования
Если у производного класса имеется несколько базовых классов, то говорят о множественном наследовании. Множественное наследование позволяет сочетать в одном производном классе свойства и поведение нескольких классов.
Если в двух базовых классах будет объявлены одинаковые по сигнатуре методы, то, когда потребуется вызвать данный метод в классе-наследнике, возникнет вопрос: какой из унаследованных методов при этом будет использован? Ведь методы, объявленные в базовых классах, имеют одинаковые имена и сигнатуры. В результате при компилировании программы возникнет неоднозначность, которую необходимо устранить, иначе компилятор вернет сообщение об ошибке.
Неоднозначность можно устранить явным обращением к необходимой функции:
Ob.ClassName::Func();
В любом случае при возникновении подобной ситуации, когда необходимо сделать выбор между одноименными методами или переменными-членами различных базовых классов, следует явно указывать имя необходимого базового класса перед именем функции-члена или переменной.
Хотя множественное наследование имеет ряд преимуществ по сравнению с одиночным, программисты неохотно используют его. Основная проблема состоит в том, многие компиляторы C++ не поддерживают множественное наследование; это затрудняет отладку программы, тем более что все возможности, реализуемые этим методом, можно получить и без него.
Рекомендуется использовать множественное наследование когда новый класс нуждается в функциях и возможностях из более чем одного базового класса.
Промежуточным решением между одиночным и множественным наследованием классов является использование классов возможностей. Так, класс Horse может происходить от двух базовых классов — Animal и Displayable, причем последний добавляет лишь несколько методов отображения объектов на экране.
Методы класса возможностей передаются в производные классы с помощью обычного наследования. Единственное отличие классов возможностей от других классов состоит в том, что они практически не содержат никаких данных. Различие довольно субъективное и отражает лишь общую тенденцию программирования, сводящуюся к тому, что добавление функциональных возможностей классам не должно сопровождаться усложнением программы.