Шаблонtuple (кортеж). Шаблон, позволяющий создавать типы для хранения безымянных членов определенных типов. Нет никаких ограничений на количество членов, для содержания которых может быть определен кортеж.
Шаблон функцииget. Шаблон функции, возвращающий определенный элемент для заданного кортежа. Например, функция get<0>(t), возвращает первый элемент из кортежа tuple t.
Глава 18
Инструменты для крупномасштабных программ
Язык С++ используется для решения проблем любой сложности — как незначительных, которые способен решить один программист за несколько часов вечером после основной работы, так и чудовищно сложных, требующих десятков миллионов строк кода и модифицируемых впоследствии на протяжении многих лет. Средства, описанные в предыдущих разделах этой книги, полезны для решения весьма широкого диапазона вопросов программирования.
Язык предоставляет некоторые средства, которые полезней в больших и сложных системах, чем в простых. Это средства обработки исключений, пространства имен и множественное наследование, являющиеся темой данной главы.
Крупномасштабное программирование предъявляет к языку более высокие требования чем те, которых достаточно для небольших групп разработчиков. К этим требованиям относятся следующие.
• Способность обрабатывать ошибки при помощи независимой подсистемы.
• Способность использовать библиотеки, разработанные более или менее независимо.
• Способность моделировать более сложные прикладные концепции.
В данной главе рассматриваются три предназначенных для этого средства языка С++: обработка исключений, пространства имен и множественное наследование.
18.1. Обработка исключений
Основы концепции применения исключений в языке С++ представлены в разделе 5.6. В данном разделе эта тема рассматривается подробней. Эффективное использование обработки исключений требует понимания происходящего при передаче исключения, его обработки и смысла объектов, сообщающих о том, что пошло не так.
18.1.1. Передача исключений
В языке С++ исключение throw (передача исключения). Тип выражения throw, вместе с текущей цепочкой вызова, определяет, какой
Когда выполняется оператор throw, расположенные после него выражения игнорируются. Оператор throw передает управление соответствующему блоку catch. Блок catch может быть локальным для той же функции или функции, непосредственно или косвенно вызвавшей ту, в которой произошла ошибка, приведшая к передаче исключения. Тот факт, что управление передается из одного места в другое, имеет два важных следствия.
• Функции можно преждевременно покидать по цепочке вызовов.
• По достижении обработчика созданные цепочкой вызова объекты будут уничтожены.
Поскольку операторы после оператора throw не выполняются, он похож на оператор return: он обычно является частью условного оператора или последним (или единственным) оператором функции.
При передаче исключения выполнение текущей функции приостанавливается и начинается поиск соответствующей директивы catch. Поиск начинается с проверки того, расположен ли оператор throw непосредственно в try (try block). Если это так, проверяется соответствие переданного объекта одному из обработчиков того блока catch, с которым связан данный блок try. Если соответствие в блоке catch найдено, исключение обрабатывается. В противном случае осуществляется выход из текущей функции, ее память освобождается, а локальные объекты удаляются. Затем поиск продолжается в вызывающей функции.
Если обращение к передавшей исключение функции находится в блоке try, проверяются обработчики того блока catch, который связан с ним. Если соответствие найдено, исключение обрабатывается. В противном случае осуществляется выход и из вызывающей функции, а поиск продолжается в той функции, которая вызвала ее, и так далее.
Этот процесс, известный как catch, а если он найден не будет, то до конца функции main().