Лекции (1129116), страница 23

Файл №1129116 Лекции (Лекции) 23 страницаЛекции (1129116) страница 232019-05-11СтудИзба
Просмтор этого файла доступен только зарегистрированным пользователям. Но у нас супер быстрая регистрация: достаточно только электронной почты!

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

у нее есть ссылка на вектор T. Что выступает в качестве класса T? В качестве класса T выступает int. Действительно происходит некое отождествление с образцов, а именно, вектор “T&” отождествляется с вектором “int”. Следовательно, можно брать первый шаблон для функции Sort для int и генерировать код.

Аналогично для Sort(a2).

В случае трех параметров компилятор находит прототип с тремя параметрами и использует их.

Мы имеем большую нагрузку на компилятор, но для программиста – все прозрачно.

Интересно то, что в первой версии шаблонов запрещались параметры-переменные в шаблонных функциях. Говорилось, что параметрами шаблонных функций могут быть только классы. То есть типовые параметры. Требовалось (и требуется), чтобы формальный парамет «тип» находился где-то в списке формальных параметров шаблонных функций. Ошибочным будет следующее определение шаблона:

template <class T> T& f( );

Почему? Механизм конкретизации шаблонов основан на правилах перекрытия. В начале наиболее точные (тождественные) совпадения. Кстати, может быть описана и не шаблонная функция Sort, главное, чтобы не было соответствия по параметрам. Следует вспомнить, что в C++ правила перекрытия определяются только по контексту параметров, но не по типу возвращаемых значений (чтобы не анализировать всевозможные контексты, в которых можно обращаться к функции).

Если мы пишем:

f( );

как мы можем провести здесь отождествление? Никак. Это означает, что T должен появляться в списке параметров. Ведь компилятор смотрит на прототип шаблона, затем на список параметров, и пытается произвести отождествление. В принципе, все просто, но вот списочек возможных контекстов, по которым производится отождествление – длинноват (порядка 15 пунктов).

Сложный вопрос – почему были проблемы с параметрами-переменными. Потому что произвести отождествление с именем просто, а что делать с размером?

Сейчас это ограничение снято, потому что в некоторых случаях можно написать:

int a[20]

f(a);

здесь компилятор может понять размер массива. Если у нас:

int *b;

или

extern c [];

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

Ну и есть контексты, для которых все корректно:

template <class T, int S>

T & f (Stack <T,S> &S);

теперь

Stack <int, 64> S; - корректно

Мы помним, что определение:

template <class T> T& f( ); - ошибочно

Но если очень хочется, то мы можем определить некоторый класс, который будет содержать лишь одну функцию f ( ). Вместо ошибочного объявления мы можем написать несколько сложных:

template <class T> class F {

public:

static T & f( );

}

здесь уже никаких проблем нет, и мы можем писать:

F<int>::f( );

Мы явным образом указываем контекст. С помощью такого трюка мы обходим ограничение.

С одной стороны механизм шаблонов в C++ очень сильный. В случае, если система программирования позволяет эффективно реализовать вышеописанную схему, то шаблонами можно и даже нужно пользоваться. Конечно же, эта схема удобнее и лучше системы родовых сегментов в Ada.

Возникает вопрос, почему, если концепция статической параметризации настолько хороша, другие языки (Delphi, Java) не поддерживают статическую параметризацию? А можно ли что-то заменить? Можно ли шаблоны смоделировать через другие средства языка. Когда мы говорили о контейнерах, то их следует рассматривать, как шаблонные классы, более того, в любой реализации C++ будет некая библиотека контейнеров, которая позволяет генерировать произвольные контейнеры. В чем достоинства и недостатки?

Достоинства очевидны, если у нас есть хэш-таблица, то достаточно реализовать код работы с ней (достаточно нетривиальный код) только один раз, а затем лишь пользоваться.

Недостатки в том, что она все же статическая. Мы не можем написать гетерогенные контейнеры, которые будут содержать объекты разных классов. Путь через (void *) делает большую дыру в защите. Да и само использование (void *) делает контейнеры ненужными.

Механизм шаблонов – очень сильное оружие, которое может рвануть в руках. Например, если мы пишем вектора для 50 типов данных, то у нас будут сгенерированы 50 одинаковых функций, и компилятор не обладает интеллектом, чтобы увидеть эту общность. Заметим, что контейнеры типа вектора на Ada можно написать, не теряя общности так, что будет сгенерирована только одна порция кода – эффективность значительно больше. Когда же программист начинает писать шаблоны сам, особенно не задумываясь над тем, что же нужно делать и что происходит, то обнаруживает в конце невероятное разбухание кода. Например:

template <class T> class Vector {

T** body; };

T1* Vector <T1*> V1;

T2* Vector <T2*> V2;

T5* Vector <T5*> V5;

Мы получим 5 различных функций.

Глава 7. Исключительные ситуации в языках программирования.

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

Интересно, что понятие исключения возникло в языках программирования достаточно рано. Уже в ранних языках программирования были так называемые ON-ситуации:

ON ситуация оператор

Примерно то же самое есть сейчас в языке Visual Basic. При возникновении ситуации (набор которых обычно был в базисе языка), выполнялся некий оператор (обычно это вызов подпрограммы), после которого, программа возобновлялась после точки его вызова, либо останавливалась. Ситуация определяет некоторое условие, при выполнении которого (далее в программе) сразу выполнялся оператор. К ситуациям, например, относились следующие константы: OVERFLOW, ERROR, ENDFILE. Что является ситуацией? С одной стороны – это набор некоторых ошибочных условий, т.е. аварийная ситуация, с другой стороны – это условия, которые зависят от внешней среды, такие как ENDFILE. С этой точки зрения, ON-ситуации можно рассматривать, как реакции на события, которые в принципе запланированы, но которые хотелось бы обрабатывать несколько нестандартным образом. Это очень похоже на те механизмы выхода из середины цикла, которые мы изучали, когда говорили о структурах управления. Сейчас существует устоявшаяся точка зрения, что исключения – это действительно аварийные ситуации, которые требуют нестандартного подхода, хотя их можно использовать и для какого-то нестандартного способа передачи управления, но этот подход является несколько порочным.

Механизм исключительных ситуаций практически одинаков во всех языках программирования, которые мы сейчас рассматриваем, что свидетельствует о том, что программисты пришли к некоторому консенсусу. Исключения, в отличие от шаблонов, есть в большом количестве языков, более того, языки, в которых они не поддерживаются, не являются языками индустриального программирования. В частности, отсутствие этой концепции в системе визуального программирования Power Builder значительно сводит на нет все достоинства этой системы.

В ранних языках программирования, исключения очень напоминали механизм обработки прерываний, реализованный на несколько более высоком уровне. Но такой механизм устарел. Современный подход, мы видим, прежде всего, в языке Ада, который с этой точки зрения повлиял и на С++. И практически в неизменном виде этот механизм присутствует в таких системах, как Delphi и Java. Самый простой механизм обработки исключений в Аде, потому что там нет наследования. Основное отличие языков Delphi и Java от C++ и Ады, состоит в том, что в первом случае, исключения являются имманентной частью языка. Мы будем рассматривать исключения во всех языках сразу, но по аспектам.

1. Объявление исключений.

В языке Ада введено специально ключевое слово exception, которое можно считать, как бы, объявлением некоторого специального типа исключений: имя:exception. На имя исключения распространяются те же самые правила видимости, что и на обычные имена объектов данных. Есть предопределенные имена исключений, которые связаны с какой-то аварийной ситуацией, которая может возбуждаться либо аппаратурой, либо механизмом квазистатического контроля. В Аде, как и в остальных языках, можно определять и свои исключительные ситуации.

В языках Delphi и Java исключения представляют собой классы. В С++ исключения – это произвольный тип данных, т.е. исключения могут быть сопоставлены типу int или char*, и т.д. С++ ввел совершенно новый подход, потому что просто идентификатор исключения несет в себе слишком мало информации. Если, например, произошел выход за границу массива, то хотелось бы знать, за границу какого массива, в какой точке, и т.д. В С++ мы можем в момент возникновения ошибки передать нужную информацию через объект исключения, туда, где она может пригодится. Java и Delphi отчасти разделили подход С++, но ограничились только классами, которые являются наследниками базовых классов (Throwable и Exception соответственно).

В классе Exception языка Delphi, например, уже есть конструктор Create, параметром которого является строка, в которую можно записать сообщение об ошибке. Если нам нужна более содержательная информация об ошибке, то мы можем вывести из этого класса свой класс, добавив в него новые возможности. Java разделяет все исключения на два класса – пользовательские, которые возбуждает пользователь, и системные, которые возбуждаются аппаратно, либо виртуальной машиной. На системные исключения программист может не реагировать, а на пользовательские исключения – обязан реагировать. Наличие базисного класса исключений дает очень много, и из-за отсутствия такого класса в С++ программу приходится начинать с конструирования своего механизма исключений.

Исключение – объявляются как некие типы данных, но в то же время, исключения не являются типами данных. Исключениям лишь соответствуют некоторые типы данных. Объекты данных соответствующего типа возникают лишь в момент возбуждения исключения.

2. Определение исключения.

Для того, чтобы определить исключение, мы должны задать некий код, который обрабатывает исключения. Зачем исключения понадобилось вводить как особую языковую конструкцию? Прежде всего, для того, чтобы отделить нормальный код (код, в котором возникают ошибки) от кода по устранению ошибок.

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

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

В языке Ада предполагается, что ошибка может возникнуть в любом месте программы и в любом месте программы ее можно обработать. Единицей кода, в которой может произойти исключение, является блок операторов, ограниченный begin и end. Блоком является тело подпрограммы, блоком является инициализационная часть тела пакета, и т.д. Везде, где могут стоять операторы, в конце некоторой их последовательности может вставляться блок по обработке исключений:

exception

when список_имен_исключений =>

операторы

when список_имен_исключений_2 =>

операторы

when others =>

операторы

Определением данного исключения является совокупность всех реакции на это исключение в зоне его видимости. Получается, что определение исключения как бы "размазано" по программе.

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

catch( тип ) { блок_реакции }

catch( тип имя ) { блок_реакции }

catch( … ) { блок_реакции }

Т.е. обработчик реагирует на ошибку данного типа и при этом может принимать дополнительную информацию. Catch c тремя точками принимает оставшиеся исключения:

try {

f();

g();

} catch( int ) { printf("int error"); }

catch( char* p ) { printf(p); }

catch( … ) { printf("error"); }

Языки Java и Delphi пошли по пути, начертанном Страуструпом. В языке Java также определяется try-блок, за которым стоят операторы catch(тип имя), но в конце также может стоять оператор finally, о котором мы поговорим несколько позже, потому что он к механизму обработки исключительных ситуаций имеет достаточно опосредованное отношение. В Java исключительные ситуации являются прямыми или косвенными наследниками класса Throwable (этот класс интегрирован в язык, и компилятор знает, что его обрабатывать нужно иначе). Поэтому компилятор следит, чтобы параметр оператора catch был наследником этого класса. Конструкцию С++ catch(…) в Java моделируется следующим образом: catch(Throwable any).

В языке Delphi все организовано почти точно также, но отличается несколько синтаксически:

try

операторы

except

on имя : тип do operator1

on имя2: тип2 do operator2

except

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

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

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

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