Bear *pb = new Panda("ying_yang");
pb->print(); //
pb->cuddle(); //
pb->highlight(); //
delete pb; //
Когда объект класса Panda
используется при помощи указателя или ссылки на класс Endangered
, части объекта класса Panda
, специфические для классов Panda
и Bear
, становятся недоступными.
Endangered *ре = new Panda("ying_yang");
pe->print(); //
pe->toes(); //
pe->cuddle(); //
pe->highlight(); //
delete pe; //
Таблица 18.1. Виртуальные функции иерархии классов ZooAnimal
/Endangered
Функция | Класс, определяющий собственную версию |
---|---|
print() | ZooAnimal::ZooAnimal |
Bear::Bear | |
Endangered::Endangered | |
Panda::Panda | |
highlight | Endangered::Endangered |
Panda::Panda | |
toes | Bear::Bear |
Panda::Panda | |
cuddle | Panda::Panda |
Деструктор | ZooAnimal::ZooAnimal |
Endangered::Endangered |
Упражнение 18.23. Используя иерархию из упражнения 18.22, а также определенный ниже класс D
и c учетом наличия у каждого класса стандартного конструктора, укажите, какие из следующих преобразований недопустимы (если таковые вообще имеются)?
class D : public X, public С { ... };
D *pd = new D;
(a) X *px = pd; (b) A *pa = pd;
(с) B *pb = pd; (d) C *pc = pd;
Упражнение 18.24. Выше представлена последовательность вызовов через указатель на класс Bear
, указывающих на объект класса Panda
. Объясните каждый вызов, подразумевая, что вместо него используется указатель на класс ZooAnimal
, указывающий на объект класса Panda
.
Упражнение 18.25. Предположим, существуют два базовых класса, Base1
и Base2
, в каждом из которых определена виртуальная функция-член по имени print()
и виртуальный деструктор. От этих базовых классов были получены следующие классы, в каждом из которых переопределена функция print()
.
class D1 : public Base1 { /* ... */ };
class D2 : public Base2 { /* ... */ };
class MI : public D1, public D2 {/* ... */ };
Используя следующие определения, укажите, какая из функций используется при каждом вызове:
Base1 *pb1 = new MI;
Base2 *pb2 = new MI;
D1 *pd1 = new MI;
D2 *pd2 = new MI;
(a) pb1->print(); (b) pd1->print(); (c) pd2->print();
(d) delete pb2; (e) delete pd1; (f) delete pd2;
18.3.3. Область видимости класса при множественном наследовании
При одиночном наследовании область видимости производного класса вкладывается в пределы его прямых и косвенных базовых классов (см. раздел 15.6). Поиск имен осуществляется по всей иерархии наследования. Имена, определенные в производном классе, скрывают совпадающие имена в базовом классе.
При множественном наследовании поиск осуществляется
В рассматриваемом примере, если имя используется через указатель, ссылку или объект класса Panda
, деревья иерархии Endangered
и Bear
/ZooAnimal
исследуются параллельно. Если имя находится в нескольких иерархиях, то возникнет неоднозначность. Для класса вполне допустимо наследовать несколько членов с тем же именем. Но если это имя необходимо использовать, следует указать, какая именно версия имеется в виду.