Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
ООП.doc
Скачиваний:
12
Добавлен:
24.09.2019
Размер:
187.39 Кб
Скачать

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

Чтобы устранить дублирование объектов непрямого базового класса при множественном наследовании, этот базовый класс объявляют виртуальным. Для этого в списке базовых классов перед именем класса необходимо поместить ключевое слово virtual. Например, класс X будет виртуальным базовым классом при таком описании:

class X { ... f(); ... };

class Y: virtual public X { ... };

class Z: virtual public X { ... );

class D: public Y, public Z { ... );

Теперь класс D будет включать только один экземпляр X, доступ х которому равноправно имеют классы Y и Z.

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

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

27) Наследование реализации.

Для того чтобы использовать функциональность методов предка для потомка, необходимо, чтобы структура данных потомка содержала все поля данных предка. Наследование функциональности обычно требует использования наследования состояния, поэтому эти два типа наследования можно объединить в один - наследование реализации. Такой механизм наследования используется для объектов в большинстве современных языков программирования, в том числе, в C++ и Java. Однако в распределенных системах наследование почти никогда не применяется.

Простейший вариант наследования реализации предполагает использование концепции делегирования: объект имеет ссылку на своего предка (предков), а тело метода, унаследованного от этого предка, состоит из переадресации вызова по ссылке. Таким образом, вызов передается от потомков к предкам, пока не будет найден объект, который способен реально выполнить этот вызов.

Несмотря на всю простоту и очевидность такого подхода, у него есть серьезный недостаток при использовании в распределенной системе: вызов передается от объекта к его предку. Но и этот предок, в свою очередь, может передавать вызов своему предку. Если иерархия наследования достаточно глубока, на один вызов метода приходится несколько последовательных удаленных вызовов. Подобные вызовы требуют значительных ресурсов, скорость работы системы может упасть в несколько раз. Следовательно, рассмотренный способ может оказаться очень неэффективным. Рассмотрим простейший пример. Ниже приведены три интерфейса на языке определения интерфейсов IDL [3].

Допустим, при создании объектов, реализующих данные интерфейсы, использовалось наследование реализации. Тогда вызов метода op_A() из объекта C будет переадресован в объект B, а оттуда — в объект A. Такая последовательность вызовов в распределенной системе потребует значительных затрат ресурсов и времени.

28) Вложенные классы в С++/С#. Вложенные классы в Java. Безымянные вложенные классы.

Иногда некоторый класс играет чисто вспомогательную роль для другого класса и используется только внутри него.

Сlass Outer{ int a;

public: class Inner{ public: void test(Outer a){ a.a=-1;} }

void f(){ Ineer in; in.test (*this) } }

int main(){ Outer o;

o.f();

Outer::Inner i;

i.test(o); }

Вложенный класс м. быть объявлен внутри отдельного метода внешнего класса. Внутренний класс можно использовать только в том методе в котором он объявлен.

В Java внутренний класс имеет доступ к локальным константам. В java можно использовать: вложенные статические, влож. не статич, внутренние и безимянные вложенные классы

Class Outer{ private int a; //влож статич. класс в java аналог влож в С++

public static class Inner{ public void test(Outer co){co.a=-1;} }

и т.д. только Outer.Inner i; // ccылка i=new Outer.Inner(); Если влож класс не статический, тогда объекты влож. класса не могут создаватся сами по себе, они должны создаваться для каких нибудь объектов внешнего класса. Методы такого влож. класса получают ссылку this на обьект внешнего класса. Outer.this

Безымянные вложенные классы. можно создавать на основе interface

class A{ public void f(){} } public class Test{public static void main(String[]argr){

interface IA{ public void f();} A ra=new A(){public void ra.f(){} }

Новый безимянный класс наследник класса А. После этого new создает обьект такого класса, возвращает ссылку на него. Новый безимянный класс, оказ. вложенным для класса Test, поэтому имеет доступ ко всем полям и методам внешнего класса Test.

29)Обработка исключений. Старые способы обработки исключительных ситуаций. Стандартная схема обработки исключений в C++. В Java. Обработка завершения.

Старые способы обработки исключительных ситуаций

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

2. Возвращающее значение(все ф-ии библ. возвращают код ошибки)

3. Setjump- сохраняет состояние процесса/longjump – откат.

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]