Сравнение языков программирования (esyr) (1161143), страница 9
Текст из файла (страница 9)
В Ada, C#, Delphi, Java множественное наследование поддерживается только для интерфейсов[11].Динамическая идентификация типа[править]Динамическая идентификация типа данных (Run-time type identification, RTTI) — механизм, который позволяет определить тип данных переменной или объекта вовремя выполнения программы.open in browser PRO versionAre you a developer? Try out the HTML to PDF APIpdfcrowd.comC++[править]В C++ для динамической идентификации типов применяются операторы dynamic_cast и typeid (определён в файле typeinfo.h), для использования которыхинформацию о типах во время выполнения обычно необходимо добавить через опции компилятора при компиляции модуля.Оператор dynamic_cast пытается выполнить приведение к указанному типу с проверкой.
Целевой тип операции должен быть типом указателя, ссылки или void*.Оператор typeid возвращ ает ссылку на структуру type_info, которая содержит поля, позволяющ ие получить информацию о типе.Delphi[править]Компилятор Delphi сохраняет в исполняемом файле программы информацию обо всех классах, используемых в ней. При создании любого объекта в памятиперед ним располагается заголовок, в котором есть в том числе ссылка на структуру-описатель класса этого объекта. Встроенные в язык функции работают с этойинформацией прозрачно для программиста.
Оператор is позволяет проверить, является ли объект или тип наследником определённого типа, а оператор asявляется аналогом dynamic_cast в C++.C#[править]В C# для определения типа объекта во время исполнения используется метод GetType, а также ключевые слова is и as, которые являются аналогами для typeid иdynamic_cast в C++ соответственно.Оберон-2[править]В Оберон-2 есть два средства для идентификации типа: операция IS и охрана типа.Проверка типа[править]v IS T означает "динамический тип v есть T (или расширение T)" и называется проверкой типа.
Проверка типа применима, если1. v - параметр-переменная типа запись, или v - указатель, и если2. T - расширение статического типа vОхрана типа[править]Операторы with выполняют последовательность операторов в зависимости от результата проверки типа и применяют охрану типа к каждому вхождениюпроверяемой переменной внутри этой последовательности операторов. Если v - параметр-переменная типа запись или переменная-указатель, и если еестатический тип T0, операторWITH v: T1 DO S1 | v: T2 DO S2 ELSE S3 ENDимеет следующ ий смысл: если динамический тип v - T1, то выполняется последовательность операторов S1 в которой v воспринимается так, будто она имеетстатический тип T1; иначе, если динамический тип v - T2, выполняется S2, где v воспринимается как имеющ ая статический тип T2; иначе выполняется S3. T1 и T2должны быть расширениями T0.
Если ни одна проверка типа не удовлетворена, а ELSE отсутствует, программа прерывается.Java[править]В Java тип объекта может быть получен при помощ и метода getClass(), объявленного в классе java.lang.Object и потому реализуемого каждым классом. Дляпроверки принадлежности объекта определенному типу используется оператор instanceof (obj instanceof SomeClass), он заменяет dynamic_cast из C++. Такжепринадлежность объекта классу может быть определена с помощ ью оператора приведения типа, который в случае несоответствия типов выбрасываетисключение ClassCastException.open in browser PRO versionAre you a developer? Try out the HTML to PDF APIpdfcrowd.comADA[править]В Аде для определения типа сущ ествует ключевое слово in работающ ее аналогично is в, скажем, Oberon-2.
После этого можно приводить типы, пользуясьмощ ным механизм конвертирования Ады (в аде вместо понятия приведения типов/type casting используется понятие конвертирование типов/type conversion):Derived_Object: Derived := Derived (Base_Object) -- Здесь будет производится проверка в run-timeПонятие о родовых объектах.
Обобщенное программирование[править]ADA[править]Note to C++ programmers: generic units are similar to C++ templates.Объявляем шаблон:generictype Element_T is private; -- Generic formal type parameterprocedure Swap (X, Y : in out Element_T);Для его использования необходимо создать объект нужного типа:procedure Swap_Integers is new Swap (Integer);Возможна перегрузка:procedure Instance_Swap is new Swap (Float);procedure Instance_Swap is new Swap (Day_T);Можно так же указывать, какие подпрограммы должны быть определены для обобщ енного типа:generictype Multiplable_T is private; -- Generic formal type parameterwith function "*" ( X, Y: Multiplable_T) return Multiplable_T;Оператор loop определяет повторное выполнение последовательности операторов.Операторы with выполняют последовательность операторов в зависимости от результата проверки типа и применяют охрану типа к каждому вхождениюпроверяемой переменной внутри этой последовательности операторов.C#[править]В C# используется конструкция where для определения ограничений на параметры родовых (другое название - обобщ енных) конструкций.
Ее вид: whereимя_типа : список_ограничений.Виды ограниченийинтерфейс — означает, что параметр-тип должен реализовывать этот интерфейс;имя класса (может быть только одно такое ограничение в списке) означает, что параметр-тип должен быть наследником этого класса;struct или class – означает, что параметр-тип должен быть структурой или классом;new() - означает, что параметр-тип должен иметь конструктор умолчания (без параметров).Are you a developer? Try out the HTML to PDF APIopen in browser PRO versionpdfcrowd.comПример универсального шаблона (generic), реализующ его односвязный список.// type parameter T in angle bracketspublic class GenericList<T>{// The nested class is also generic on T.private class Node{// T used in non-generic constructor.public Node(T t){next = null;data = t;}private Node next;public Node Next{get { return next; }set { next = value; }}// T as private member data type.private T data;// T as return type of property.public T Data{get { return data; }set { data = value; }}}private Node head;// constructorpublic GenericList(){head = null;}// T as method parameter type:public void AddHead(T t){Node n = new Node(t);n.Next = head;head = n;}public IEnumerator<T> GetEnumerator(){Node current = head;while (current != null){yield return current.Data;current = current.Next;}}}Параллельное программирование[править]ADA[править]Ада реализует концепцию так называемых задач (task), что по сути является синонимом потока.
Задача оформляется совершенно аналогично модулю, но можетбыть объявлена и описана где угодно, даже в теле подпрограммы:package Tasked isprocedure Tasked_proc istask Untyped_task_1 isSome declarationsend task;open in browser PRO version-- Здесь объявляем все так, как будто объявляем пакетAre you a developer? Try out the HTML to PDF APIpdfcrowd.comend task;task Untyped_task_2;-- Мы можем ничего и не открывать в задаче внешнему миру-- Мы можем объявлять как отдельные задачиtask type Task_Type is -- Так и целые типы задачSome declarationsend Task_Type;Typed_task_1, Typed_task_2 : Task_Type;-- Две одинаковые задачиtask body Untyped_task_1 is separate; -- Можно описать задачу отдельноtask body Untyped_task_2 issomething is separate;-- Или часть задачи отдельноbegin...-- Собственно то, что будет делать задачаend;end Untyped_task_2;task body Task_Type is...end Task_Type;-- Тело типа задачи-- Тут начинают работать наши 4 задачи параллельно: Untyped_task_1, Untyped_task_2, Typed_task_1, Typed_task_2-- На самом деле их 5, так как главный процесс рассматривается как неявная задачаbegin-- Tasked_procDo_Something;...-- Здесь задача, запустившая потомков будет ожидать их завершенияend Tasked_proc;end Tasked;В Аде есть множество методов синхронизации задач.
Рассмотрим один из них - entry. Это что-то на подобии точек входа в задачу извне. По своему объявлению,это - самые обычные процедуры, однако описываются и работают они по-другому. Когда одна задача хочет запросить у другой какую-либо услугу, она вызываетentry, которая реализовывает данную услугу. В теле задачи (непосредственно в выполняемом коде), реализующ ей услугу есть участки кода, описывающ их телаentry. Описание начинается со слова accept . Задача, вызвавшая entry будет ожидать, когда задача, реализующ ая этот entry дойдет до его тела.
Этот моментназывается Rendezvou (рандеву, свидание). Если несколько задач, одновременно (это слово, естественно, не стоит воспринимать буквально) вызвали entry, тоони становятся в очередь (тут уже речь идет, наверное, о названии Orgy хD ). Как это все выглядит:task type Service istype Some_Type is range -10 .. 10;entry Plus ( X: in Some_Type );entry Minus ( X: in Some_Type );entry Get ( X: out Some_Type ); -- Повторюсь, entry - те же процедуры у которых могут быть in/out параметры.end Service;Кроме того для того чтобы задача не простаивала, тела accept можно объединить в блок select, который будет выбирать запрошенные entry,task body Service isSome_Var: Some_Type;beginSome_Var := 0;loopaccept Get ( X: out Some_Type ) do -- Здесь будем простаивать, пока кто-нибудь не запросит Get;X := Some_Var;end Get;selectaccept Plus ( X: in Some_Type ) doSome_Var := Some_Var + X;end Plus;oraccept Minus ( X: in Some_Type ) doSome_Var := Some_Var - X;end Minus;end select;end loop;open in browser PRO version-- Здесь либо сразу выполняем одно из запрошенных (Plus, Minus), либо ждем, пока придет запрос на один из этих entityAre you a developer? Try out the HTML to PDF APIpdfcrowd.comend loop;end Service;В этом примере, естественно лучше было все 3 accept запихнуть в select - было бы меньше простоев, но для примера я оставил так.Modula-2[править]В языке Modula-2 есть низкоуровневый механизм сопрограмм.Отличия сопрограммы от процесса:1.