Программирование >>  Инициализация объектов класса, структура 

1 ... 318 319 320 [ 321 ] 322 323 324 ... 395


Raccoon meeko( обитель всякой еды );

члена, унаследованной из ZooAnimial:

meeko. onExhibit (); ZooAAnimal: : onExhibit ()

Производный класс Panda наследует члены своих базовых классов. Их можно отнести к одной из трех категорий:

члены виртуального базового класса ZooAnimial, такие, как name () и family(), не замещенные ни в Bear, ни в Raccoon;

член onExhibit() виртуального базового класса ZooAnimial, наследуем1й при обращении через Raccoon и замещенный в классе Bear;

специализированные в классах Bear и Raccoon экземпляры функции print() из ZooAnimial.

Можно ли, не опасаясь неоднозначности, напрямую обращаться к унаследованным членам из области видимости класса Panda? В случае невиртуального наследования -нет: все неквалифицированные ссылки на имя неоднозначны. Что касается виртуального наследования, то прямое обращение допустимо к любым членам из первой и второй категорий. Например, дан объект класса Panda:

Panda spot( Spottie );

Тогда инструкция

spot.name();

вызывает разделяемую функцию-член name() виртуального базового ZooAnimal, а инструкция

spot.onExhibit(); вызывает функцию-член onExhibit() производного класса Bear.

18.5.4. Видимость членов виртуального базового класса

Изменим наш класс Bear так, чтобы он имел собственную реализацию функции-члена onExhibit(), предоставляемой также ZooAnimial:

bool Bear::onExhibit() { ... } Теперь обращение к onExhibit() через объект Bear разрешается в пользу экземпляра,

Bear winnie ( обитель меда ) ;

определенного в этом классе:

winnie.onExhibit(); Bear::onExhibit ()

Обращение же к onExhibit() через объект Raccoon разрешается в пользу функции-



ошибка: неоднозначно при невиртуальном наследовании Panda yolo ( обитель бамбука );

onExhibit() через объект Panda неоднозначно:

yolo.onExhibit();

В данном случае все унаследованные экземпляры имеют равные приоритеты при разрешении имени, поэтому неквалифицированное обращение приводит к ошибке комниляции из-за неоднозначности (см. раздел 18.4.1).

При виртуальном наследовании члену, унаследованному из виртуального базового класса, приписывается меньший приоритет, чем члену с тем же именем, замещенному в производном. Так, унаследованному от Bear экземпляру onExhibit() отдается

правильно: при виртуальном наследовании неоднозначности нет вызывается Bear::onExhibit()

предпочтение перед экземпляром из ZooAnimal, унаследованному через Raccoon:

yolo.onExhibit();

Если два или более классов на одном и том же уровне наследования замещают некоторый член виртуального базового, то в производном они будут иметь одинаковый вес. Например, если в Raccoon также определен член onExhibit() , то при обращении к нему из Panda придется квалифицировать имя с помощью оператора разрешения области

bool Panda::onExhibit()

return Bear::onExhibit() &&

Raccoon::onExhibit() && ! sleeping;

видимости:

Упражнение 18.13 Дана иерархия классов:

Когда два или более экземпляров члена наследуются разными путями (это относится не только к функциям-членам, но и к данным-членам, а также к вложенным типам) и все они представляют один и тот же член виртуального базового класса, неоднозначности не возникает, поскольку существует единственный разделяемый экземпляр (первая категория). Если один экземпляр представляет член виртуального базового, а другой -член унаследованного от него класса, то неоднозначности также не возникает: специализированному экземпляру из производного класса отдается предпочтение по сравнению с разделяемым экземпляром из виртуального базового (вторая категория). Но если оба экземпляра представляют члены производных классов, то прямое обращение неоднозначно. Лучше всего разрешить эту ситуацию, предоставив замещающий экземпляр в производном классе (третья категория).

Например, при невиртуальном наследовании неквалифицированное обращение к



class Class { ... };

class Base : public Class { ... };

class Derived1 : virtual public Base { ... };

class Derived2 : virtual public Base { ... };

class MI : public Derived1,

public Derived2

Derived2 { ... }; class Final : public MI, public Class {

(a) В каком порядке вызываются конструкторы и деструкторы при определении объекта

Final?

(b) Сколько подобъектов класса Base содержит объект Final? А сколько подобъектов

Class?

Base MI

Class

*pb;

*pmi;

*pc;

Derived2 *pd2;

(i) pb = new Class; (iii) pmi = pb;

(c) Какие из следующих присваиваний вызывают ошибку компиляции?

(ii) pc = new Final; (iv) pd2 = pmi;

Упражнение 18.14 Дана иерархия классов:



1 ... 318 319 320 [ 321 ] 322 323 324 ... 395

© 2006 - 2024 pmbk.ru. Генерация страницы: 0.001
При копировании материалов приветствуются ссылки.
Яндекс.Метрика