Студопедия — Виртуальные базовые классы
Студопедия Главная Случайная страница Обратная связь

Разделы: Автомобили Астрономия Биология География Дом и сад Другие языки Другое Информатика История Культура Литература Логика Математика Медицина Металлургия Механика Образование Охрана труда Педагогика Политика Право Психология Религия Риторика Социология Спорт Строительство Технология Туризм Физика Философия Финансы Химия Черчение Экология Экономика Электроника

Виртуальные базовые классы






В сложной иерархии классов при множественном наследовании может получиться так, что производ­ный класс косвенно унаследует два или более экземпляра одного и того же класса. Рассмотрим пример, который проясняет эту ситуацию.

class Ground // базовый класс

{

int x; public:

int GetX () { return x; }

void SetX (int X) { x = X; } }

class Basel: public Ground // наследует базовый класс Ground

{

• • •
}

class Base2: public Ground // наследует базовый класс Ground

{

• • •
}

class Derived: public Base1, public Base2 // производный класс – наследник классов Base1 и Base2

{

• • •
}

void main () {

Derived ob; // создание объекта производного класса

ob.SetX (1); int z = A.GetX (); }

Здесь класс Derived косвенно наследует класс Ground через свои базовые классы Base1 и Base2. Поэтому при компиляции приведенного примера возникнут ошибки, вызванные неоднозначностью обра­щения к членам класса GetX () в строках: ob.SetX (0); int z = A.GetX ();

Чтобы избежать этой неоднозначности, можно использовать квалификацию имен, применив опера­цию разрешения видимости:

ob.Base1:: SetX (1); int z = A.Base1:: GetX ();

Можно также квалифицировать эти вызовы следующим образом:

ob.Base2:: SetX (1);
int z = A.Base2:: GetX ();
Хотя этот способ и позволяет избежать неоднозначности при вызове, тем не менее, класс Ground
будет включен в состав класса Derived дважды, увеличивая его размер. Избежать повторного включения
косвенного базового класса в производный класс можно, дав указание компилятору использовать вирту­
альный базовый класс. Это осуществляется с помощью ключевого слова virtual, которое указывается пе­
ред спецификатором наследуемого доступа или после него. Следующий пример является модифициро­
ванным вариантом предыдущего, использующим класс Ground в качестве виртуального базового класса.
class Ground // базовый класс

{

int x; public:

int GetX () { return x; }

void SetX (int X) { x = X; } }



Объектно-ориентированное программирование


Лекция 6


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



class Basel: virtual public Ground // наследует класс Ground как виртуальный класс

{

• • •
}

class Base2: virtual public Ground // наследует класс Ground как виртуальный класс

{

• • •
}

class Derived: public Base1, public Base2 // производный класс – наследник классов Base1 и Base2

{

• • •
}

void main () {

Derived ob; // создание объекта производного класса

ob.SetX (1); int z = A.GetX (); }

В этом случае класс Derived содержит один экземпляр класса Ground, и вызовы ob.SetX (1); int z = A.GetX ();

не приводят к появлению сообщений компилятора об ошибках, связанных с неоднозначностью.

Отсюда следует общая рекомендация: если разрабатывается иерархия классов и данный класс на­следуется несколькими классами, включите перед спецификаторами наследуемого доступа ключевое слово virtual, то есть наследуйте его как виртуальный базовый класс.

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

Объявление базового класса виртуальным изменяет порядок вызова конструкторов при создании эк­земпляра производного класса. Конструкторы виртуальных базовых классов вызываются первыми, рань­ше конструкторов невиртуатьных базовых классов. Если виртуальных базовых классов несколько, их кон­структоры вызываются в порядке их объявления в списке наследования. Затем вызываются конструкторы невиртуальных базовых классов в порядке их объявления в списке наследования и, наконец, вызывается конструктор производного класса. Если какой-то виртуальный класс является производным невиртуально­го базового класса, этот невиртуальный базовый класс конструируется первым (иначе нельзя будет вы­звать конструктор виртуального базового класса).

Если иерархия классов содержит несколько экземпляров виртуального базового класса, этот базовый класс конструируется только один раз. Если все же существуют как виртуальный, так и невиртуальный эк­земпляры этого базового класса, конструктор базового класса вызывается один раз для всех виртуальных экземпляров этого базового класса, а затем еще раз для каждого невиртуального экземпляра этого базо­вого класса.

Деструкторы вызываются в порядке, в точности обратном конструкторам.



Объектно-ориентированное программирование







Дата добавления: 2015-08-17; просмотров: 380. Нарушение авторских прав; Мы поможем в написании вашей работы!



Вычисление основной дактилоскопической формулы Вычислением основной дактоформулы обычно занимается следователь. Для этого все десять пальцев разбиваются на пять пар...

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

Кардиналистский и ординалистский подходы Кардиналистский (количественный подход) к анализу полезности основан на представлении о возможности измерения различных благ в условных единицах полезности...

Обзор компонентов Multisim Компоненты – это основа любой схемы, это все элементы, из которых она состоит. Multisim оперирует с двумя категориями...

ЛЕЧЕБНО-ПРОФИЛАКТИЧЕСКОЙ ПОМОЩИ НАСЕЛЕНИЮ В УСЛОВИЯХ ОМС 001. Основными путями развития поликлинической помощи взрослому населению в новых экономических условиях являются все...

МЕТОДИКА ИЗУЧЕНИЯ МОРФЕМНОГО СОСТАВА СЛОВА В НАЧАЛЬНЫХ КЛАССАХ В практике речевого общения широко известен следующий факт: как взрослые...

СИНТАКСИЧЕСКАЯ РАБОТА В СИСТЕМЕ РАЗВИТИЯ РЕЧИ УЧАЩИХСЯ В языке различаются уровни — уровень слова (лексический), уровень словосочетания и предложения (синтаксический) и уровень Словосочетание в этом смысле может рассматриваться как переходное звено от лексического уровня к синтаксическому...

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

Тема: Кинематика поступательного и вращательного движения. 1. Твердое тело начинает вращаться вокруг оси Z с угловой скоростью, проекция которой изменяется со временем 1. Твердое тело начинает вращаться вокруг оси Z с угловой скоростью...

Условия приобретения статуса индивидуального предпринимателя. В соответствии с п. 1 ст. 23 ГК РФ гражданин вправе заниматься предпринимательской деятельностью без образования юридического лица с момента государственной регистрации в качестве индивидуального предпринимателя. Каковы же условия такой регистрации и...

Studopedia.info - Студопедия - 2014-2024 год . (0.012 сек.) русская версия | украинская версия