Теория и реализация языков программирования

       

Множественное наследование


Имея два класса

class A {. . . af (int);} class B {. . . bf (int); }

можно объявить третий класс с этими двумя в качестве базовых:

class C : public A, public B {. . . }

Объект класса C может быть размещен как непрерывный объект вида:


Рис. 9.17. 

Как и в случае с единичным наследованием, здесь не гарантируется порядок выделения памяти для базовых классов, поэтому объект класса C может выглядеть и так:


Рис. 9.18. 

Доступ к члену класса A, B или C реализуется в точности так же, как и для единичного наследования: компилятор знает положение в объекте каждого члена и порождает соответствующий код.

Если объект размещен в памяти в соответствии с первой диаграммой: сначала часть A объекта, а затем части B и C, то вызов функции - члена класса A или C будет таким же, как вызов функции-члена при единичном наследовании. Вызов функции-члена класса B для объекта, заданного указателем на C, реализуется несколько сложнее. Рассмотрим

C* pc = new C; pc

bf(2);

Функция B :: bf() естественно предполагает, что ее параметр this является указателем на B. Чтобы получить указатель на часть B объекта C, следует добавить к указателю pc смещение B относительно C - константу времени компиляции, которую мы будем называть delta(B). Соотношение указателя pc и указателя this, передаваемого в B::bf, показано ниже.


Рис. 9.19. 



Содержание раздела