Когда программа конструируется из отдельных модулей, особенно когда модули находятся вне зависимо разработанных библиотеках, обработка ошибок должна быть разделена на две части:
1) генерация информации о возникновении ошибочной ситуации, которая не может быть решена локально;
2) обработка ошибок, обнаруженных в других местах.
2) логические ошибки, связанные с предметной областью (выход за пределы значений диапазона, несоответствие множеству заданных значений);
3) на усмотрение разработчика.
Автор библиотеки может обнаружить ошибки во время выполнения, как правило, не знает, что делать в этом случае, а пользователь может знать, как поступить при возникновении ошибки, но но не может найти их. Поэтому в языках C++ и Java введено понятие исключений. Суть исключений в том, что функция или метод, обнаружив проблему, возбуждают исключения в надежде, что вызывавшая её функция решит проблему.
Механизм обработки исключений позволяет отделить код обработки ошибок от собственного кода алгоритма, делая программу более понятной.
Блок кода, который может вызвать ошибку, помещают в try { … }. Если при выполнении блока программист сразу предусматривает некоторую ошибку, он может использовать throw для того, чтобы передать управление коду из соответствующего блока в catch( … ) { … }. Параметром блока catch будет служить определенный тип, при работе с которым произошла ошибка либо который передает throw. Блоков catch () может быть несколько, при этом располагать их необходимо в порядке, учитывая, что при ошибке соответствующий обработчик исключения будет отдавать приоритет тому catch, который стоит раньше в коде; это следует учитывать при расположении блоков catch, т.к. при поиске необходимого обработчика может произойти неявное преобразования типа. Последним устанавливается блок catch(…) с тремя точками, который обрабатывает любую ошибку независимо от её типа.
Иными словами, за одним try-блоком могут следовать несколько catch-блоков. Оператор catch, с указанным вместо типа исключения многоточием, перехватывает исключения любого типа и должен быть последним из операторов catch, следующих за try-блоком.
39. Библиотеки классов на C++.
Расширение стандартных библиотек языка C связанное с функциями, основанными на шаблонах, называется библиотекой шаблонов.
Standard
Template Lib, STL
Основными структурами данных библиотек являются шаблоны классов для представления стеков, очередей, векторов, списков и т.д. Стандартизация повышает надежность и мобильность программ. Все классы этой библиотеки имеют набор родовых алгоритмов (шаблонов функций общего вида для манипулирования с различными контейнерами). Такое разделение функций (когда контейнеры хранят данные, а алгоритмы оперируют ими) позволило сократить объем библиотеки.
Основная часть библиотеки не использует свойства ОО-ти (наследование и вирт. ф-ции). Подход, основанных на шаблонах, усиливает свойства языка C++.
Одним из важных понятий библиотеки наряду с контейнером и родовым алгоритмом является итератор – класс, объекты которого обеспечивают доступ к компонентам контейнера. Итератор обобщает понятие указателя, позволяет перебирать компоненты контейнера. Итератор может указывать на конкретный компонент.
40. Библиотека для организации ввода вывода в потоки. Библиотека контейнерных классов CLASSLIB в BORLAND C++. Библиотеки OWL и MFC.
Object Windows Library (OWL) — библиотека классов, разработанная фирмой Borland для создания оконных приложений на языках Си и Pascal. Данная библиотека использовалась во многих средствах программирования компании Borland, таких как Turbo Pascal for Windows, Borland Pascal, Borland C++, C++ Builder и других. Эта библиотека соперничала с Microsoft Foundation Classes.
Библиотека классов ObjectWindows зависит от библиотеки контейнерных классов в подкаталоге CLASSLIB. Все объекты ObjectWindows совместно используют класс Object (определяемый в библиотеке контейнерных классов) как свой базовый класс. В классах ObjectWindows также используются некоторые другие классы из этой библиотеки. В ваших программах ObjectWindows вы можете использовать любые из контейнерных классов.
Помимо стандартных для С++ файлов заголовка , как STDIO.H, вашей прикладной программе возможно потребуются дополнительные файлы заголовков ObjectWindows, например OWL.H. В этом случае для вспомогательных утилит вы будете обязаны указывать их местонахождение. Для написания программ с использованием библиотеки ObjectWindows вы обязательно должны включать, по крайней мере, файл OWL.H. Более сложные приложения требуют включения и других файлов заголовков. Например, программа, использующая класс TButton, должна включать BUTTON.Н. Прикладные программы ObjectWindows и сама ObjectWindows основываются на библиотеке контейнерных классов, поставляемой с ObjectWindows, поэтому вы обязательно должны включать путь поиска включаемой библиотеки контейнерных классов ObjectWindows.
Всем прикладным программам необходим доступ к стандартным библиотекам Borland C++, плюс, к созданным вами самими и полученным от третьих лиц. Кроме этого, приложения ObjectWindows требуют доступа к поставляемым библиотекам контейнерных классов ObjectWindows и стандартным библиотекам ObjectWindows.
В следующей таблице приведены создаваемые установочными утилитами по умолчанию имена каталогов ObjectWindows или Borland C++. Если в установочной утилите вы зададите другие имена, то вам нужно будет внести соответствующие изменения в MAKE файлы и файлы проектов.
Пакет Microsoft Foundation Classes (MFC) — библиотека на языке C++, разработанная Microsoft и призванная облегчить разработку GUI-приложений для Microsoft Windows путем использования богатого набора библиотечных классов.
Библиотека MFC, как и её основной конкурент, Borland VCL, облегчает работу с GUI путем создания каркаса приложения — «скелетной» программы, автоматически создаваемой по заданному макету интерфейса и полностью берущей на себя рутинные действия по его обслуживанию (отработка оконных событий, пересылка данных между внутренними буферами элементов и переменными программы и т. п.). Программисту после генерации каркаса приложения необходимо только вписать код в места, где требуются специальные действия. Каркас должен иметь вполне определенную структуру, поэтому для его генерации и изменения в Visual C++ предусмотрены мастера.
Кроме того, MFC предоставляет объектно-ориентированный слой оберток (англ. wrappers) над множеством функций Windows API, делающий несколько более удобной работу с ними. Этот слой представляет множество встроенных в систему объектов (окна, виджеты, файлы и т. п.) в виде классов и опять же берет на себя рутинные действия вроде закрытия дескрипторов и выделения/освобождения памяти.
Добавление кода приложения к каркасу реализовано двумя способами. Первый использует механизм наследования: основные программные структуры каркаса представлены в виде классов, наследуемых от библиотечных. В этих классах предусмотрено множество виртуальных функций, вызываемых в определенные моменты работы программы. Путем доопределения (в большинстве случаев необходимо вызвать функцию базового класса) этих функций программист может добавлять выполнение в эти моменты своего кода.
Второй способ используется для добавления обработчиков оконных событий. Мастер создает внутри каркасов классов, связанных с окнами, специальные массивы — карты (оконных) сообщений (англ. message map), содержащие пары «ИД сообщения — указатель на обработчик». При добавлении/удалении обработчика мастер вносит изменения в соответствующую карту сообщений.
ASSERT
Макрос проверяет переданное ему выражение на истинность(то есть true или false). Если выражение true — программа выполняется дальше, если false — программа аварийно завершается(подробнее далее). Давайте напишем пример, который проиллюстрирует работу макроса:
#include <assert.h> //подключаем заголовочный файл для assert
#include <stdio.h>
int main(int argc, char *argv[])
{
printf("Выполнение assert(true)rn"); //выводим на экран строку
assert(0 == 0); //передаем в assert TRUE
printf("Выполнение assert(false)rn"); //выводим на экран строку
assert(0 == 1); //передаем в assert FALSE
/*Пытаемся вывести еще одну строку, но этот код не будет выполнен
так как предыдущий assert завершил выполнение программы*/
printf("Завершение программыrn");
return 0;
}