Использование конструкторов и деструкторов при наследовании



Значения конструктору базового класса передаются через список инициализации. Который должен располагаться после двоеточия между списком параметров и телом конструктора. Внутри списка инициализации указывается название базового класса, после которого внутри круглых скобок передаются значения. При создании экземпляра производного класса в случае иерархического наследования в начале вызывается конструктор самого первого базового класса в цепочке наследования. Далее вызываются последовательно конструкторы всех остальных базовых классов. И лишь затем вызывается конструктор производного класса.Деструкторы вызываются в обратном порядке.

При использовании множественного наследования используется следующий формат объявления производного класса:

class<Производный класс> :

[<Спецификатор доступа>] <Базовый класс1>,

[<Спецификатор доступа>] <Базовый класс2>,

{

<Объявление членов класса> }

[<Объявление переменных через запятую>];

 

 

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

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

Если производный класс наследует несколько классов, которые в свою очередь наследуют один и тот же базовый класс, то возникает неоднозначность, тк один и тот же член базового класса будет присутствовать в нескольких классах. В приведенном примере классы «В» и «С» являются наследниками класса «А», в котором объявлен метод «func1», существует в двух экземплярах, если создать экземпляр класса «D» и попытаться обратиться к методу «func1», то компилятор выдаст сообщение об ошибке.
Одним из способов разрешения неоднозначности является явное указание базового класса и оператора «::» перед названием метода при вызове. При другом способе, чтобы метод был только в единственном экземпляре, следует объявить классы «В» и «С» виртуальными. Для этого в списке наследования перед спецификатором доступа следует указать ключевое слово «virtual». В этом случае никакой неоднозначности не будет, поэтому можно вызывать метод «func1» без явного указания класса.

Использование объектно-ориентированных средств приводит к снижению производительности программ по следующим причинам:

· Динамическое связывание методов. Обеспечение полиморфизма в поведении объектов приводит к необходимости связывать методы, вызываемые программой. То есть определять, какой конкретно метод будет вызываться, не на этапе компиляции, а в процессе выполнения программы на что будет тратиться дополнительное время. При этом реальное динамическое связывание требуется не более чем для 20% вызовов. В то время как некоторые языки ООП используют его постоянно.

· Значительная глубина абстракции. Объектно-ориентированная разработка часто приводит к созданию “многослойных” приложений, где выполнение объектом требуемого действия сводится к множеству обращений к объектам более низкого уровня. В таком приложении очень много методов и возвратов из методов, что, естественно, сказывается на производительности.

· Наследование «Размывает код». Код, относящийся к конечным классам иерархии наследования, которые обычно и используются программой непосредственно, находятся не только в самих этих классах, но и в их классах предков. Относящиеся к одному классу методы фактически описываются в разных классах. Это приводит к двум неприятным моментам:

- Снижается скорость трансляции, тк компоновщику приходится подгружать описание всех классов иерархии

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

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

· Динамическое создание и уничтожение объектов. Динамически создаваемые объекты, как правило, размещаются в динамической памяти (куче), что менее эффективно, чем размещение в стеке. Тем более, чем статическое выделение памяти под них на этапе компиляции.

Несмотря на видимые недостатки, выгоды от использования ООП более весомые. Можно заметить, что многие эффекты снижения производительности могут сглаживаться или даже полностью устраняться на счёт качественной оптимизации кода компилятора.


Дата добавления: 2018-06-27; просмотров: 467; Мы поможем в написании вашей работы!

Поделиться с друзьями:






Мы поможем в написании ваших работ!