   void D::f( void )
   { 
       Display();      // ??? Двусмысленно; не скомпилируется 
       А:: Display О;    // Вызов функции-члена А 
       В:: DisplayO;    // Вызов функции-члена В 
   }
    
    Использование конструкторов нескольких базовых классов 

    В классе, выведенном из нескольких базовых, также может возникнуть 
необходимость в вызове конструкторов этих классов. Если классы А, В и С имеют 
конструкторы по умолчанию, в производном классе D их можно вызвать следующим образом:	

    сlass D:  public A,  public В,  public С { 
    public:
       D():  А(),   В(),   с()  {  }	// Встраиваемый конструктор 
       ........
     };

    Или же конструктор можно объявить как 

    class D:   public A,   public В,   public С { 
    public: 
        D() ;	// Конструктор,  реализованный снаружи 
        ......
    }; 

    и реализовать отдельно, обычно, в другом файле: 

    D:.D() 
       :  А(),   В(),   С() 
    {	
        ... // Операторы в конструкторе D() 
    }
 
    Конечно, конструкторы могут иметь различные параметры, не использующиеся в 
данном примере. Конструкторы вызываются в том порядке, в котором объявлены их 
базовые классы. Было бы неразумно придумывать классы, зависящие от того, в 
каком порядке будут созданы объекты других классов. Как правило, классы 
должны действовать независимо друг от друга настолько, насколько-это вообще возможно. 

    ЗАМЕЧАНИЕ 

    Предположим, класс зависит от того, в каком порядке будут 
проинициализированы его компоненты. Вместо того чтобы выводить один класс, 
наследующий свойства других классов, вы можете объявить зависимый клаcc в 
качестве данных-членов нового класса. А новый класс сможет управлять местом и 
временем инициализации членов зависимого класса. 

    Использование виртуальных базовых классов 

    Производные классы и их базовые классы образуют иерархию, которая может 
достичь невероятной сложности даже в относительно простых программах. Базовый 
класс может наследоваться одним и более классами, которые, в свою очередь, могут 
стать базовыми для еще большего числа классов. Следовательно, все эти классы 
связаны отношениями простого и множественного наследования и, подобно библейским 
персонажам, один из них порождается другим до тех пор, пока уже никто не сможет сказать, 
кто к кому относится. 
    Легко понять, почему возникают конфликты в сложной иерархии классов, 
особенно когда дело касается множественного наследования. Один из самых 
распространенных конфликтов возникает, когда производный класс наследует 
слишком много копий некоторых базовых классов, подобно победителю лотереи, 
который в один прекрасный день обнаруживает, что у него невероятное количество 
"троюродных сестер", о существовании которых он раньше даже не подозревал. 
    Для демонстрации того, как в производных классах возникают неприятности, 
связанные с наследованием, ознакомьтесь с классами программы, приведенной в 
листинге 14.8. В программе используется сложная взаимосвязь между тремя 
фиктивными компаниями и тремя вымышленными инвесторами: Бобом (Bob), Тедом 
Ted) и Алисой (Alice). Программа может показаться неудачной шуткой, однако 
заимствование тесных взаимосвязей из реальной жизни поможет объяснить 
типичные и зачастую доводящие до белого каления проблемы, возникающие с 
множественным наследованием. 


    Глава 14. Объектно-ориентированное программирование 361 
