C++.Бархатный путь



         

Виртуальные классы - часть 2


ОписательБазы ::= ПолноеИмяКласса

::= [virtual] [СпецификаторДоступа] ПолноеИмяКласса

::= [СпецификаторДоступа] [virtual] ПолноеИмяКласса

Модифицируем нашу программу. Мы добавим в описатели баз производных классов B и C спецификатор virtual:

class A { public: int x0; int Fun1(int key); }; class B: virtual public A { public: int x0; int Fun1(int key); int Fun2(int key); }; class C: public virtual A { public: int x0; int Fun2(int key); }; class D: public B, public C { public: int x0; int Fun1(int key); };

Вот как выглядит после модификации граф производного класса D:

A B C D

А вот как меняется структура класса D, представляемая в виде неполной схемы. Спецификатор virtual способствует минимизации структуры производного класса. Виртуальные базовые классы не тиражируются.

A B C D

А вот и схема объекта-представителя класса D.

D MyD; MyD ::= A (int)x0; (int)xA; B (int)xB; C (int)x0; D (int)x0; (int)xD;

Спецификатор virtual в описании базы позволяет минимизировать структуру объекта. Различные варианты обращения к данным-членам базового фрагмента приводят к модификации одних и тех же переменных.

Базовый фрагмент объекта связан со своими производными фрагментами множеством путей, по которым с одинаковым успехом может быть обеспечен доступ к данным-членам базового фрагмента.

В C++ допускаются такие варианты объявления производных классов, при которых одни и те же классы одновременно выступают в роли виртуальных и невиртуальных базовых классов. Например, сам класс D может быть использован в качестве базового класса:

class F: public A { ::::: } class G: public A, public D { ::::: } ::::: G MyG;

Множество одноименных виртуальных и невиртуальных базовых фрагментов, данных-членов, простых и виртуальных функций. Можно до бесконечности рисовать направленные ациклические графы, диаграммы классов и объектов… Искусство объявления классов и навигации по фрагментам объектов совершенствуется в результате напряжённой длительной практики.

Введём новое понятие, связанное с доступом к данным и функциям-членам производных классов.

Имя x (имя переменной, класса, или функции), объявленное в классе X, обозначается как X::x. Имя B::f доминирует над именем A::f, если объявление класса B содержит в списке баз имя класса A.

На понятии доминирования имён основывается правило доминирования, определяющее корректность доступа к членам производного класса, объявленного на основе виртуальных базовых классов.

Это правило гласит, что возможность достижения по пути направленного ациклического графа нескольких одноименных функций либо данных-членов приводит к неоднозначности, за исключением случая, когда между именами существует отношение доминирования.




Содержание  Назад  Вперед