|
Программирование >> Инициализация объектов класса, структура
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 Дана иерархия классов:
|
© 2006 - 2024 pmbk.ru. Генерация страницы: 0.001
При копировании материалов приветствуются ссылки. |