Лекция 16 (1160814), страница 3

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

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

try{

блок

}catch(E1 e){…}

catch(E2 e){…}

В этих языках нет catch(…) потому, что любое исключение принадлежит соответствующему типу – DException, Exception или Throwable. Поэтому здесь такая конструкция не нужна. Вместо того, что писать catch(…) пишут, например, на языке Java

catch(Throwable e){…}

Это аналог catch(…). В С++ если все исключения являются потомками одного предка, catch(…) писать не надо. В данном случае мы можем из е получить хоть какую-то информацию. Такой catch должен стоять последним, поскольку все типы так или иначе выведены из Throwable.

В Delphi несколько другой синтаксис, но смысл тот же

try

операторы

except

on [имя:]тип do опер;

end;

Оператор после do может быть составным. В том случае, если нам не надо получать информацию из объекта, имя может отсутствовать.

Чем дальше от корневого типа стоит тип в цепочке наследования, тем выше он должен стоять в списке обработчиков исключений.

Исключение считается обработанным, если нормальным образом завершился блок обработки исключения.

Как видно семантика практически одна и та же. Но есть, конечно, свои специфические особенности. Рассмотрим их.

В языке Java есть понятие спецификации исключительных ситуаций. Это в некоторой степени роднит его с С++. В С++ эта спецификация необязательна. В языке Java спецификация исключительных ситуаций является обязательной.

void f( ){

throw new Err( );

}

В этом месте компилятор выдаст ошибку потому, что в языке Java спецификация исключительных ситуаций является обязательной. По этому коду компилятор видит, что исключительная ситуация throw new Err( ) является необработанной потому, что она находится вне try-блока.

Err должен быть классом, выведенным из класса Throwable, иначе компилятор выдаст ошибку.

Throw может встречаться внутри try-блока, тогда если это исключение можно перехватить внутри него, то все в порядке, если – нет, то он помечает, что этот блок может выбрасывать исключения типа Err. Если оно находится вне блока, то f может выбрасывать ситуацию типа Err. Значит, она должна быть специфицирована. Спецификация исключительных ситуаций в Java имеет вид

void f( ) throws(Err) {

throw new Err( );

}

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

Раз спецификация исключительных ситуаций является обязательной, то статически можно проследить, какие исключения могут быть выданы на протяжении всей программы. Требование обязательной обработки исключительных ситуаций приводит к тому, что программиста заставляют писать эти исключительные ситуации. Как следствие, писать обработку ошибок и отказоустойчивые программы вообще на языке Java, оказывается значительно приятней, чем на других языках. В хорошей библиотеке на С++, в документации везде стоят соответствующие спецификации. Но они стоят в документации, и их можно просто проигнорировать, и компилятор не выдаст ошибки. В данном случае если проигнорировать спецификацию, компилятор выдаст ошибку. Поскольку все объекты, за исключением простых переменных, заводятся в динамической памяти, то практически любая функция на языке Java будет порождать новые объекты и может выбросить везде, где встречается new, исключение типа MemoryException. В результате получается, что мы должны писать throws практически в спецификации исключений каждой функции. К числу ошибок в языке Java относится ошибка виртуальной Java-машины. Для программиста на языке Java компьютера не существует, для него существует только виртуальная Java-машина. Т.е. фатальный сбой виртуальной Java-машины говорит о том, что не работает компьютер. Программным образом эту ошибку никак не исправить. Когда встречается такая ошибка надо сразу рапортовать разработчику виртуальной Java-машины, поскольку в процессе функционирования любой, даже ошибочной программы такие ошибки выдаваться не должны. Но по принципу Мерфи, если они могут появиться, они появятся. Причем они могут появиться в любом месте.

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

Базовый тип Throwable

Error Exception

"UserExeption" RuntimeExeption

MemoryException

"UsepException" – пользовательские исключения.

MemoryException частный случай RuntimeException. В Java динамическая сборка мусора поэтому, если динамический сборщик мусора говорит, что памяти больше нет, то взять ее неоткуда. Т.е. исправить ошибку, которая связана с MemoryException, мы не можем.

Классы, которые выведены из Error – это классы типа ошибка виртуальной Java-машины… Они нужны для сигнализации неисправимых ошибок. К сожалению не все ошибки можно исправить в программе. Если загорелась проводка, работать дальше программе не имеет смысла. В Java есть исключения, на которые мы обязаны реагировать, а есть исключения, на которые мы не обязаны реагировать. На исключения типа Error и на все исключения, которые выведены из RuntimeException мы не обязаны реагировать. И как следствие мы не обязаны их указывать в списке спецификаций исключений. Но все "UserException" мы указывать обязаны.

В C#, Delphi нет такого очень удобного механизма как в языке Java. Java изначально разрабатывалась как многоплатформенная среда, работающая на базе одного языка. Т.е. предполагается, что при работе на Java используется только Java. В рамках одного языка выразить подобного рода механизм не сложно. C# - это язык, который включен в систему .NET, базовой для которой является система базисных классов NET.Framework. Идея NET.Framework в том, что имеется базисная система типов и базисный набор компонент, который не зависит от языка. Все языки, входящие в систему .NET (сейчас это порядка 10 языков, в том числе C#), работают с единой библиотекой. Принципы обработки исключений в этих языках немного различаются. Например, в языке Basic принципы обработки исключений отличны от принципов обработки исключений, которые мы сейчас разбирали. Поэтому вводить какую-то единообразную технику в этих языках не представляется возможным.

Механизмы, отличные от тех, которые мы рассмотрели.

Главная идея обработки исключений, в языках, которые мы рассмотрели – динамическая ловушка (семантика завершения). Кроме семантики завершения есть, как назвал это Кауфман, ремонт на месте (семантика возобновления). В Visual Basic есть семантика возобновления.

on error вызов процедуры или оператор перехода

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

raise;

  • перевозбудить ошибку, пусть она идет на более высокий уровень.

resume;

  • возобновить оператор, на котором произошла ошибка.

resume next;

  • пропустить оператор, на котором произошла ошибка, и выполнять следующий.

pause;

Семантика resume и есть семантика возобновления. В такой семантике возможна ситуация, что ошибочный оператор, блок, который вызвал ошибку, будет перезапущен – то, что отсутствовало в семантике завершения. raise говорит о том, что блок не может обработать ошибку и поэтому она распространяется на более высокий уровень. raise позволяет реализовывать семантику завершения. Получается, что семантика возобновления является более мощной. Т.е. она может моделировать семантику завершения и в то же время в ней есть дополнительные полезные свойства. Когда в 90-м году обсуждалась модель исключений, которую собирались включить в предполагаемый стандарт языка С++, было 2 точки зрения:

  1. семантика завершения, как она была предложена Страуструпом на базе языка Ада

  2. семантика восстановления, на которой настаивали представители Microsoft.

В DOS, если забыли вставить дискету, система говорит

Abort Retry Ignore

Abort – значит raise. Retry – resume. Ignore – resume next. Это чистая семантика возобновления. Оказывается, что в некоторых частных случаях семантика возобновления работает очень хорошо. Все современные серьезные языки программирования применяют семантику завершения, хотя это частный случай семантики возобновления, а семантика возобновления не особенно более накладна (во многих источниках указано, что реализация семантики возобновления немножко сложнее, но накладные расходы примерно те же самые). Оказалось, что это тот самый случай, когда употребление более общей конструкции приводит к плохому коду. Одним из главных аргументов, после которого комитет по стандартизации языка С++ склонился к семантике завершения, было не то, что на той семантике настаивал Страуструп, а то, что реальные специалисты, которые писали действительно отказоустойчивые системы пришли к выводу, что с точки зрения обеспечения структурности и надежности механизма отказоустойчивости лучше использовать семантику завершения, т.е. более частную конструкцию. Решающим стало выступление разработчиков, которые разрабатывали отказоустойчивые системы на базе Cedar/Mesa из знаменитого исследовательского центра Xerox PAC фирмы Xerox Palau Alta. Они начинали свою работу, будучи сторонниками семантики обработки исключительных ситуаций по возобновлению. Общий проект занял порядка 10 миллионов строк кода. Потом они были вынуждены перейти к семантике завершения. И выяснилось, что из 10 миллионов строк кода только в одном случае действительно использовалась семантика возобновления. И там, можно было обойтись без нее. Люди, которые склонялись к одной семантике, и в то же время пытались писать отказоустойчивую программу, перешли на семантику завершения потому, что, на самом деле, ситуации, когда можно сделать ремонт на месте очень редки, и их можно свести к семантике завершения. Реально исправить ошибку на месте нельзя. Семантика возобновления опасна тем, что она создает иллюзию, что можно отремонтироваться на месте.

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

for(;;){

try{

… - тут возникает нехватка ресурсов

}

catch(…){… - попытка найти этот ресурс}

}

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

Глава 9. Статическая параметризация.

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

void f(X x)

очень мало динамической информации о типе передается вместе с фактическим параметром. Поэтому, единственное, что мы можем параметризовать – это объекты данных, поскольку механизм типизации достаточно хорошо характеризует, какие именно объекты данных мы передаем, по крайней мере их размер. Но если мы используем статическую параметризацию, то можно расширить список объектов, которые можно параметризовать. Основное достоинство статической параметризации в противовес динамической – то, что если динамически параметризуются только объекты данных, т.е. переменные или константы. При статической параметризации - объекты данных (функции тоже являются объектами данных, т.к. в языках есть процедурные типы данных) + типы данных. Пример: стек. Допустим мы выбрали какую-то стратегию реализации стека, например через массив, т.е. статический стек – стек с фиксированной длиной, и тогда у нас возникают 2 вопроса

  • какой длины брать стек

  • какой тип элементов в этом стеке

Если бы не было статической параметризации, для каждого типа элементов стека нужно было бы писать свой стек. В языках, где нет статической параметризации, используют, чтобы не писать для каждого типа данных свой стек, указатели. Если язык не объектно-ориентированный, то это нечто типа стек из void*. void* – это тот самый горшочек, в который вы можете положить все, что угодно, но под вашу ответственность. В языках с объектным стилем программирования есть так называемая динамическая информация о типе – RTTI –Run Time Type Identification. Там есть специальные методы. В языке Delphy, в языке Java, в языке C# все коллекции – структуры данных типа стек и т.д. также представляют из себя структуру данных, правда не из указателей, а из ссылок. И далее работа идет с помощью механизма идентификации типа. Но статическая параметризация позволяет нам избежать соответствующих накладных расходов. Она позволяет нам параметризовывать не только длину элементов стека, но и их тип. Из рассматриваемых нами 2 языка, содержат статическая параметризация. В языке Ада это механизм родовых сегментов (родовых модулей). В языке С++ - это механизм шаблонов. Существует 2 подхода, когда нам надо параметризовать некоторые более общие свойства, т.е свойства, которые в общем случае связаны с типом объекта. Один – это механизм статической параметризации, другой – механизм, основанный на динамической идентификации типа. Еще в конце 80-ых г.г. известный специалист в области ООП опубликовал статью, в которой обосновал, что механизм динамической идентификации типа, который основан на понятии наследования является более общим, чем механизм статической параметризации в любом языке. Мы еще раз сталкиваемся с ситуацией, что иногда более общие механизмы не всегда являются более подходящими. В С++ есть и динамическая идентификация типа. В Аде 95 – объектно-ориентированном расширении Ады – тоже есть динамическая идентификация типа. Хорошо или нет иметь статическую параметризацию в языке – вопрос спорный. Фирма Borland в свое время объявила, что никакой статической параметризации в их языке (Delphi) не будет. Когда появился C#, один из основных дискуссионных моментов был, почему там нет никакого родового программирования. (Родовое программирование – программирование, основанное на статической параметризации.) И оно не появилась.

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

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

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

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