Языки программирования, 27 лекция (от 12 декабря)
Материал из ESyr's Wiki pages.
Предыдущая лекция | Следующая лекция
Предварительный экзамен 19 декабря. На нём нельзя пользоваться книгами. Пересдача на пересдаче.
RTTI
Си++
Отличие от JD#: Во-первых, вопрос RTTI, не может ставится для любых обхектов, только для тех, которые могут иметь дин тип, то есть только для T* и T&. В JD# все объекты из Object, а он уже с RRTI, в С++ только для типов, у которых есть вирт методы, то есть только у тех, которые имеют таблицу вирт функ, которая имеет инф о типе.
такая реализация RTTI, это не снижает мощность для языка. RTTI нужна для безоп проеобр от базового класса к производному, чтобы вызывать методы производного, которые привязаны динамически.
С++: dynamic_cast<T*>(e) – динамическое преобр типа – похоже на страж типа. Проверяется тип, то возвр указатель, иначе возвр 0 (t is T в Обероне)
dynamic_cast<T&>(e) – если можно делается преобр, иначе исключение, потому что нулевой ссылки нет, поэтому Страуструп утверждал, что первый вариант – проверка, страж типа; а второй – утверждение. (t(T) в Обероне)
Для унификации синтаксиса появились static_cast<T>(e) – неконтроллируемое преобр указателя. reinterpret_cast<T>(e) – когда тип e и T никак не свзаны, например, указатель и инт.
С# в managed code позволяет только dynamic_cast.
В С++ появилась ещё одна конструкция – type_info typeid(t) – псевдофункция, возвр специальный тип type_info. Псевдофункция потому, что применима к именам типом. type_info содержит слде методы: void before(type_info&), const char * name(). У него перерыты == и !=.
JD# - изначально объектно ориент, и в них всё хорошо. Там можно получить полную динамическую информацию о типе. В них появился Reflection. Можно получить список всех методов, имена всех методов, типа и имена параметров, все интерфейсы, все базовые классы.
Есть строка «A.B.C», можно проверить что такое A, B, C.
Есть ядро, написанное высокопроизводительном статическом языке, например Апач написан на Си, оболочка на скриптовых языках
System.Reflection, там есть Assembly, которая позволяет узнать инфомацию о сборке, которая позволяет сказать getTypes, которая возвращает вписок типов. В java.lang есть классс Class, который хранит всю информацию о классе. И есть Object.getClass(), который позвояет получить класс. Механизм отражения в Джаве нужен затем, что там есть динамическая загрузка классов.
Множественное наследование
Очень спорный вопрос. Есть пуристы, которые говорят, что если в Смолтоке чего-то нет, то это не нужно. Множественное наследование реализовано C++, Eiffel, CLOS (Common Lisp Object System – максимальный язык).
1986 – С++ 2.0 – продакшн версия, AT&T представила язык, до этого С++ распространялся freeware. 2.0 стали использовать компании. Когда был дедлайн, С. отложил темплейты и занялся наследованием. Позже он говорил, что был Objective C, и автор его писал, что реализовать множ наследование невозможно. Механизм шаблонов был сформирован в 1991 году, но в студлии он полностью не реализован до сих пор. STL – платформа, которая состоит из исходников и компилятор. Та STL, которая была, на вижуалке не компилировалась.
Детали мех мноэ наследования: внешне просто, у класса может быть несколько баз. class X: public B1, public B2 ... {...}. В чём проблемы: проблема имён. Если и там и там есть одинаковые имена Name. Если функции-члены, то вызываем их так: X* x = new X; x->B1::Name x->B2->Name;
А если: из B наследуют C, D, из них X. Сю приводил пример: Storable
void read(); void write();
Transmitter
void write
Receiver
void read
Проблема реализ множ наследования свфязана с реализ дин связывания.
//педедыв
Link
|
V ProcessList, UserList
|
V Process Можно сделать Link как член класса
Есть класс TR, который унаследовал от Transmitter и Receiver. Как будет выглядеть его ТВМ?
TR * p = new TR(); p -> read(); - унасл от rec p -> write(); - унасл от trans
Здесь нарушается правило С++ - если польз-прогр не использует что-то, то оно не присоединяется. Если не исп искл, то их нет, если не исп. множ насл, то польз должны платить,
Diamond – ромбовидное (бубновое, !!!не бриллиантовое) наследование
base_io istream, ostream iostream
//как говорил науч рук лектора, если делать, то по-большому
Двойной указатель уже не проходит. Мы даже не знаем, глде находится ТВМ. Эффективная реализация невозм. С. сделал достаточно эффективнуюб реализацию, но она кривая.
Это наследование С. назвал виртуальным.
class Base { ... };
class D1:public virtual Base {..} class D2:public virtual Base {..} class X:public D1, public D2 {..}
Соотв, мы должны сообщать о ромбовидном насл уже на этапе D1, D2. Поэтому это самый спорный аспект.
При насл интерфейсов проблем не возникает.
Что такое интерфейс – ссылка на ТВМ и this.
Если отсут нестат члены-данные, то сложностей никаких.
Последняя глава и тема нашего курса:
Глава 5. Статическая параметризация
Мы можем выбирать по форме, профилю функции, поэтому можно выбирать её на этапе компиляции.
Можно пойти дальше и параметризовывать не только функции, но и типы.
Статич параметр менее мощная, чем дин. В дин можно проэмулировать стат.
В Дельфи нет. В шарп появилсаь с версии 2.0
Рассм Аду, С++, С#.
В С++ наиболее гибкий, поэтому наиболее трудно реализ.
п.1 Язык Ада.
Родовые модули (generic) Могут быть: 1.пакеты 2.подпрограммы
Синтаксис: Объявление родового объекта generic
объявл стат параметров
спецификация пакета | заголовок подпрограммы
Вызов абстракции – instantiation – конкретизация
package IntStack is new Stack(...); procedure IntSort is new Sort(...);
в Аде рдовые модули были введены таким хитрым образом, что они всё поддерживали – разд компиляция, ..., причём эффективо.
generic
size: integer; type ElType is private;
package Stack is
procedure Push(X: ElType); function Pop() return ElType; function IsFull() return Boolean;
end Stack;
Если посм специф пакета, он выдаёт голыые процедуры, которые будут работать с типом, который объявлен в теле пакета.
package body Stack is
body : array [1..size] of ElType; top : integer:=1;
end Stack;
package IntStack is new Stack(64, integer);
генерируется новая специф. пакета
IntStack.Push(0); - чисто объектная запись
Для конкретизации можно знать только спецификацию пакета – разд компиляция.
Как только требуется, чтобы нам нужно было выполнять нетрив операции, мы должны передавать всю информацию.
Надо сообщить процедуре сортировки, указать тип элемента, тип индекса, функцию сравнения – так что она должна иметь 4 родовых параметра, хотя можно было бы только один, а остальные выводить.
Доходим до идиотизма: родовой вариант функции MapList – у неё 8 родовых параметров.
Языки Программирования
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
Календарь
чт | вт | чт | вт | чт | вт | чт | вт | чт | вт | |
Сентябрь
| 05 | 07 | 12 | 14 | 19 | 21 | 26 | 28 | ||
Октябрь
| 03 | 05 | 10 | 12 | 17 | 19 | 24 | 26 | 31 | |
Ноябрь
| 02 | 14 | 16 | 21 | 23 | 28 | 30 | |||
Декабрь
| 05 | 07 | 12 | 14 | 19 |