лекции (2011) (1160854), страница 9

Файл №1160854 лекции (2011) (лекции (2011)) 9 страницалекции (2011) (1160854) страница 92019-09-19СтудИзба
Просмтор этого файла доступен только зарегистрированным пользователям. Но у нас супер быстрая регистрация: достаточно только электронной почты!

Текст из файла (страница 9)

X * py = new Y(); // уже здесь компилятор выдаст ошибку из-за того, т.к. непонятно что записывать в таблицу виртуальных функций

py -> f();

X a; // здесь компилятор также выдаст ошибку из-за того, из-за того, что не сможет заполнить таблицу виртуальных функций. Если бы функция X:: f() не была виртуальной, то ошибки здесь не было бы.

a.g();// ошибка, т.к X::g() не определена

Решение проблемы – языковая поддержка

В C#, Java:

abstract перед классом и перед функцией, для которой не существует реализации на данном уровне детализации. Такие функции и классы, их содержащие, называют аббстрактными

abstract class base //Абстрактный класс

{

abstract public void Draw(); // Функция без реализации

}

С#

class D: base{
public override void draw(){……};

};

Java

class D: extends base{
public override void draw(){……};

};

//обязательно поставить тело Draw!

В C++:

Чисто виртуальная функция (абстрактная) – virtual «прототип» = 0;

В Аде:

procedure P( X : T ) is abstract;

где T – тегированный тип.

Объекты абстрактных классов нельзя создавать.

При вызове виртуальной функции в конструкторе виртуальность вызова снимается.

Существует метод, который не должен быть чисто виртуальным – деструктор. Он всегда должен быть виртуальным и реализованным.

Различие между абстрактными классами и абстрактными типами данных:

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

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

Абстрактный класс (АК) — это класс, содержащий хотя бы один абстрактный метод.

class Iset

{

virtual void include(const T &) = 0;

virtual exclude(const T &) = 0;

«статические члены»

}

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

Множественное наследование интерфейсов. Реализация интерфейсов и ее

особенности современных ЯП. Явная и неявная реализация интерфейсов.

В C# и Java, в отличие от C++, существует языкового понятия интерфейса:

interface «имя»

{

«объявления членов»

}

Внутри интерфейса могут быть статические поля. Поля без «static» будут восприняты как статические. Также членами интерфейса могут быть методы и свойства, которые считаются чисто виртуальными и публичными.

Т.е. интерфейс – чистый контракт, не реализующий структуру.

Если класс наследует интерфейс и не определяет все методы интерфейса, то он становится абстрактным.

Если написать

int pi{gte; set}

то оно превратится в свойство.

Кстати, перед определением свойства может стоять слово virtual. То есть свойства могут быть виртуальными или чисто виртуальными.

В Java вместо get и set есть getpair и setpair.

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

C#

class D: имя, интерфейсы:

Java

Class D extends Base implements именя интерфейсов

Интерфейсы могут содержать внутри себя любые вложенные классы.

В С# появляется так называемая явная и неявная реализация интерфейсов.

Неявная реализация – это то, что мы всегда называем обычной реализацией.

Пример неявной реализации интерфейсов:

interface ISample{

void f(); };

class CoClass: ISample{

public void f(){………………..}; //если тут не поставить public, компилятор заругается.

};

Явная реализация интерфейсов:

class CoClass2: ISample{

void ISample f() {…………….}

//тут спецификатор public отсутствует, потому что попытка написать тут public карается

};

Как же вызвать данный метод, если он не публичный?

D * px;

px->f(); //непонятно, какой метд я хочу вызывать – ошибка.

Но px->I1::f(); //снова ошибка: попытка вызова чисто виртуальной функции.

Мы же хотим вызвать заместителя для I1. Это длается так:

((I1*)px)->f();

Замечание. Слова «явный» и «неявный» должны относиться к приведению типов, а не к классам(интерфейсам).

CoClass2 x;

(ISample)x.f();//явное приведение

При явной реализации вызов возможен лишь ри явом приведении.

Явная реализация интерфейса означает, что вызов метода

интерфейса может происходить только через ссылку на интерфейс, но неможет происходить через ссылку на класс, реализующий интерфейс. Перед

вызовом интерфейсного метода необходимо явно преобразовать ссылку на

объект реализующего класса к ссылке на интерфейс. Концепция явной

реализации полезна, например, при конфликте имен между унаследованными

интерфейсами.

В C# реализованные методы интерфейсов считаются по умолчанию «sealed» - запечатанными. В наследниках они перекрываются.

class ExampleClass : IControl

{

public void Paint(){ … ;}

}

class FancyComBox: ExampleClass

{

public void Paint(){….; } // Компилятор выдаст предупреждение для этой строчки, в котором сообщит, что «FancyComBox.Paint() скрывает унаследованный метод ExampleClass.Paint(). Используйте ключевое слово «new», если это сделано целенаправленно. Т.е. если поставить «new» перед определением, то предупреждение исчезнет.

Замечание2. Интерфейсы-маркеры.Реализованы в Ада. Являюются разновидностью стандартных интерфейсов, относящихся к категории ссылочных типов. Цель маркеров состоит в том, чтобы вызов через интерфейс был равносиелн по эффективности вызову виртуального метода.

Java: Iterable.

Интерфейсы-маркеры – это стандартные интерфейсы, доведенные до абсолюта. Контракт интерфейсов-маркеров описан только в документации. Это пустые интерфейсы, мы не можем увидеть их с своем коде.

Пример: интерфейс Cloneable – класс, поддерживающий этот интерфейс, обязан реализовать метод Clone

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

Множественное наследование в языке Си++. Ромбовидное

наследование и его примеры. Проблемы множественного наследования:

конфликт имен, реализация динамического связывания. Особенности

реализации множественного наследования при наследовании интерфейсов.

С какими проблемами мы сталкиваемся при множественном наследовании?

  • Конфликт имен

  • Виртуальные методы.

Конфликт имен решается через явное указание имени базы или через приведение к ссылке на базу.

Но существует ещё одна проблема – эффективность динамического полиморфизма (виртуальных функций)

А теперь рассмотрим множественное

class A

{

public:

A(){};

virtual void a(){ a1 = 1;};

virtual void second(){..;}

int a1, a2, a3;

};

class B

{

public:

B(){};

virtual void bar(){};

virtual void bbar(){};

int b1, b2, b3;

};

class C : public A

{

public:

C() : A(){};

virtual void goo(){};// Собственная новая виртуальная функция

void a(){}; // переопределение

void bar();// переопределение

int c1;

};

….

C c;

Тут надо обратить внимание на следующее:

• Таблица виртуальных методов самого нижнего класса в иерархии доступна через первый указатель vptr.

• Каждый подобъект, который содержит виртуальные методы, имеет свою таблицу виртуальных функций.

Если в классе C переопределить метод, то в соответствующую ячейку в таблице родительского объекта будет записан указатель на новый метод. Если же в классе C добавляются новые функции – они дописываются в конец первой таблицы.

Такой алгоритм становится понятен, если рассмотреть возможные преобразования типов:

• С -> A. Через указатель на класс A можно вызывать только методы, которые прописаны в этом классе.

• C -> B. Ситуация аналогична, только мы можем вызывать виртуальные методы, определенные в классе B.

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

Сложность реализации заключается в следующем:

Во время преобразования типов меняется адрес указателя:

C c;

B *p = &c;

Указатель p будет содержать адрес объекта c + смещение подобъекта B. Т.е. все вызовы методов через такой указатель будут использовать вторую таблицу виртуальных методов объекта C. Но ведь в такой ситуации при вызове переопределённой в C функции через указатель на B в эту функцию передастся неправильный указатель this! Он будет указывать не на C, как это нужно, а на B.

Приходится расширять таблицу виртуальных функций добавлением в неё смещения от указателя на объект класса до таблицы виртуальных функций для каждой функции. Если виртуальная функция из B переопределена в C, то для неё такое смещение будет равно (-смещение подобъекта B). Если же не была переопределена, то оно будет равно нулю. Для всех виртуальных функций из класса A это смещение будет нулевым, т.к. указатель на подобъект A совпадает с указателем на весь объект C(объект А находится в начале

объекта C). Теперь в функцию можно передать правильный указатель:

this = current_this + offset

где current_this – на подобъект, через который вызывается функция. offset – значение, которое берётся из расширенной таблицы виртуальных функций.

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

Ромбовидное и не ромбовидное наследование

Не ромбовидное: : В объекте Z будет два экземпляра объекта A с разными реализациями таблицы виртуальных функций

сlass A{ .. ;}

class X:public A{ …; }

class Y:public A{… ; }

class Z: public X, public Y {…;}

Ромбовидное: В объекте Z будет только один экземпляр объекта A

сlass A{ .. ;}

class X: public virtual A{ …; }

class Y: public virtual A{… ; }

class Z: public X, public Y {…;}

13. Динамическая идентификация типа

Понятие о динамической идентификации типа (ДИТ). Достоинства и

недостатки использования ДИТ. Особенности ДИТ в современных языках

программирования.

14. Понятие о родовых объектах. Обобщенное программирование

Понятие о статической параметризации и родовых объектах.

Достоинства статической параметризации. Статическая параметризация и

ООП.

Родовые модули и подпрограммы в языке Ада.

Порождение нового пакета порождало новый экземпляр данного типа.

package Stack – два параметра – тип элемента размер стека:

generic

type T is private;

size: integer;

package Stack is

Push

Pop

end Stack;

Можно ли так запрограммировать процедуры, чтобы они эффективно работали для любого размера стека? Конечно, да!

Конкретизация:

package IStack is new Stack(integer, 128);

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

В Аде большое разнообразие типов формальных параметров родового модуля. Формальные параметры родовых модулей:

параметр-переменная <=> любое константное выражение
type T is private <=> любой тип с операцией присваивания
type T is range <=> любой дискретный тип с упорядоченностью и функциями «следующий» и «предыдущий»
type T is delta <=> любое плавающее выражение
< > <=> при конкретизации процедуры мы можем не указывать этот вариант (параметр по умолчанию).

Пусть у нас есть:

procedure StrSort is new G_SORT(String, Integer, TARR);

C помощью < > компилятор находит функцию < для строк и подставляет как параметр по умолчанию. Родовые сегменты – абсолютно необходимая в Аде конструкция, потому что там нет передачи процедур и функций по параметру. Компилятор должен видеть не только спецификацию данной абстракции, но и тело. Гибкость повышается, но тело родовой абстракции должно быть доступно в любой момент конкретизации. В Аде-83 механизм родовых модулей – единственный, который поддерживал ОО. Как вы думаете, что самое главное, что появилось в Аде-95? Правильно, класс – тегированная запись:

type T is tagged

Механизм шаблонов в языке Си++. Шаблоны-классы и шаблоны-

функции. Параметры шаблонов. Вывод параметров шаблонов. Генерация

кода по шаблонам. Частичная специализация шаблонов. Обобщенное

программирование на языке Си++: функторы, свойства, стратегии, шаблоны

выражений.

Характеристики

Тип файла
Документ
Размер
452 Kb
Материал
Тип материала
Высшее учебное заведение

Список файлов лекций

Свежие статьи
Популярно сейчас
Почему делать на заказ в разы дороже, чем купить готовую учебную работу на СтудИзбе? Наши учебные работы продаются каждый год, тогда как большинство заказов выполняются с нуля. Найдите подходящий учебный материал на СтудИзбе!
Ответы на популярные вопросы
Да! Наши авторы собирают и выкладывают те работы, которые сдаются в Вашем учебном заведении ежегодно и уже проверены преподавателями.
Да! У нас любой человек может выложить любую учебную работу и зарабатывать на её продажах! Но каждый учебный материал публикуется только после тщательной проверки администрацией.
Вернём деньги! А если быть более точными, то автору даётся немного времени на исправление, а если не исправит или выйдет время, то вернём деньги в полном объёме!
Да! На равне с готовыми студенческими работами у нас продаются услуги. Цены на услуги видны сразу, то есть Вам нужно только указать параметры и сразу можно оплачивать.
Отзывы студентов
Ставлю 10/10
Все нравится, очень удобный сайт, помогает в учебе. Кроме этого, можно заработать самому, выставляя готовые учебные материалы на продажу здесь. Рейтинги и отзывы на преподавателей очень помогают сориентироваться в начале нового семестра. Спасибо за такую функцию. Ставлю максимальную оценку.
Лучшая платформа для успешной сдачи сессии
Познакомился со СтудИзбой благодаря своему другу, очень нравится интерфейс, количество доступных файлов, цена, в общем, все прекрасно. Даже сам продаю какие-то свои работы.
Студизба ван лав ❤
Очень офигенный сайт для студентов. Много полезных учебных материалов. Пользуюсь студизбой с октября 2021 года. Серьёзных нареканий нет. Хотелось бы, что бы ввели подписочную модель и сделали материалы дешевле 300 рублей в рамках подписки бесплатными.
Отличный сайт
Лично меня всё устраивает - и покупка, и продажа; и цены, и возможность предпросмотра куска файла, и обилие бесплатных файлов (в подборках по авторам, читай, ВУЗам и факультетам). Есть определённые баги, но всё решаемо, да и администраторы реагируют в течение суток.
Маленький отзыв о большом помощнике!
Студизба спасает в те моменты, когда сроки горят, а работ накопилось достаточно. Довольно удобный сайт с простой навигацией и огромным количеством материалов.
Студ. Изба как крупнейший сборник работ для студентов
Тут дофига бывает всего полезного. Печально, что бывают предметы по которым даже одного бесплатного решения нет, но это скорее вопрос к студентам. В остальном всё здорово.
Спасательный островок
Если уже не успеваешь разобраться или застрял на каком-то задание поможет тебе быстро и недорого решить твою проблему.
Всё и так отлично
Всё очень удобно. Особенно круто, что есть система бонусов и можно выводить остатки денег. Очень много качественных бесплатных файлов.
Отзыв о системе "Студизба"
Отличная платформа для распространения работ, востребованных студентами. Хорошо налаженная и качественная работа сайта, огромная база заданий и аудитория.
Отличный помощник
Отличный сайт с кучей полезных файлов, позволяющий найти много методичек / учебников / отзывов о вузах и преподователях.
Отлично помогает студентам в любой момент для решения трудных и незамедлительных задач
Хотелось бы больше конкретной информации о преподавателях. А так в принципе хороший сайт, всегда им пользуюсь и ни разу не было желания прекратить. Хороший сайт для помощи студентам, удобный и приятный интерфейс. Из недостатков можно выделить только отсутствия небольшого количества файлов.
Спасибо за шикарный сайт
Великолепный сайт на котором студент за не большие деньги может найти помощь с дз, проектами курсовыми, лабораторными, а также узнать отзывы на преподавателей и бесплатно скачать пособия.
Популярные преподаватели
Добавляйте материалы
и зарабатывайте!
Продажи идут автоматически
6363
Авторов
на СтудИзбе
310
Средний доход
с одного платного файла
Обучение Подробнее