
- •1. Понятие класса. Методы класса. Управление доступом к компонентам.
- •2. Объявление и определение класса. Внешнее определение функций.
- •3. Создание, копирование и удаление объекта.
- •4. Статические компоненты класса. Инициализация статических компонентов класса.
- •5. Наследование. Типы наследования. Виртуальное наследование.
- •6. Виртуальные функции
- •7. Абстрактные классы и чистые виртуальные функции. Интерфейс
- •8. Дружественность. Дружественные классы и функции.
- •9. Вложенные классы. Внутреннее и внешнее определение.
- •10. Шаблоны классов
- •11.Создание экземпляров шаблона. Инстанцирование.
- •12.Шаблоны и наследование.
- •13.Терминология шаблонов.
- •14. Параметры и аргументы шаблона.
- •15. Шаблоны компонентных функций
- •16. Полная специализация шаблонов.
- •17. Частичная специализация шаблонов.
- •18. Перегрузка операций. Основные понятия.
- •19. Перегрузка унарных операций.
- •20. Перегрузка бинарных операций.
- •Int test() {
- •Int test() {
- •Int test() {
- •// Делаем что-то
- •Вопрос 23
- •24. Группировка и композиция исключений. Повторная генерация. Перехват всех исключений.
- •25. Автоматическое управление ресурсами. Методика raii.
- •Void f() { FileOpen("myfile.Txt", "rt"); //здесь выполняем нужную работу с файлом //... }
- •Void f (int a) throw (x2, x3)
- •27. Стандартная библиотека. Организация стандартной библиотеки
- •28. Тип вектора. Вложенные типы. Итераторы. Доступ к элементам
- •29.Тип Вектора. Конструкторы. Операции со стеком. Списочные операции. Размеры и емкость.
- •30. Стандартные контейнеры. Вопросы производительности операций.
- •31. Процесс разработки по. Цели и этапы проектирования.
- •32. Процесс разработки по. Выявление классов. Определение операций.
- •33. Процесс разработки по. Определение взаимосвязей. Определение интерфейсов.
- •Этап 3: выявление зависимостей
- •Этап 4: определение интерфейсов
- •34. Паттерны проектирования. Основные паттерны.
- •35. Тестирование по. Методы тестирования.
Вопрос 23
Концепции исключений:
Обнаружение ошибок и порождение исключений
Перехват ошибки и выполнение ответных действий
Разделение порождения исключений и перехвата необходимо, т.к. при возникновении ошибки не известно, какие действия нужно предпринимать для ее устранения
Синтаксис порождения и перехвата исключений
If (divisor ==0) throw int();
Try
{
float amgle=math (…);
}
В операторных скобках {} контролируемый блок начинается со слова try, далее блок исключения:
catch (int)
{
}
Раскрутка стека
Поиск catch-обработчикадля возбужденного исключения происходит следующим образом. Когда выражение throw находится в try-блоке, все ассоциированные с ним предложения catch исследуются с точки зрения того, могут ли они обработать исключение. Если подходящее предложение catch найдено, то исключение обрабатывается. В противном случае поиск продолжается в вызывающей функции. Предположим, что вызов функции, выполнение которой прекратилось в результате исключения, погружен в try-блок; в такой ситуации исследуются все предложения catch, ассоциированные с этим блоком. Если один из них может обработать исключение, то процесс заканчивается. В противном случае переходим к следующей по порядку вызывающей функции. Этот поиск последовательно проводится во всей цепочке вложенных вызовов. Как только будет найдено подходящее предложение, управление передается в соответствующий обработчик.
Процесс, в результате которого программа последовательно покидает составные инструкции и определения функций в поисках предложения catch, способного обработать возникшее исключение, называется раскруткой стека. По мере раскрутки прекращают существование локальные объекты, объявленные в составных инструкциях и определениях функций, из которых произошел выход. C++ гарантирует, что во время описанного процесса вызываются деструкторы локальных объектов классов, хотя они исчезают из-за возбужденного исключения.
24. Группировка и композиция исключений. Повторная генерация. Перехват всех исключений.
В стандартной библиотеке есть базовый класс исключений std: exeption
Повторная генерация
25. Автоматическое управление ресурсами. Методика raii.
Принцип "выделение ресурса есть инициализация" удобно использовать при выделении любого типа ресурсов. Это позволяет сделать работу программы более надежной. Использование этого принципа особенно важно, если в ходе работы приложения могут возникать исключительные ситуации. В этом случае сложно заранее предусмотреть, в какой именно момент возникнет исключение и какие необходимые действия не будут совершены в результате преждевременного завершения программы. Например, если приложение открывает какой-нибудь файл или выделяет блок памяти, то при завершении работы приложения желательно соответственно закрыть файл или освободить выделенный блок памяти. Однако исключение может быть сгенерировано еще до того, как будет выполнена инструкция, закрывающая файл или освобождающая блок памяти. В результате эта инструкция так и не будет выполнена:
void f() { FILE* pf; if ((pf = fopen("myfile.txt", "rt")) == NULL) { //не удалось открыть файл exit(1); } //здесь выполняем нужную работу с файлом //и здесь может возникнуть какое-нибудь исключение //... //если исключение возникнет, то до этой строки мы не доберемся //и файл не будет закрыт fclose(pf); } Если подобных ситуаций необходимо избегать, то лучше организовать работу с файлом, соблюдая принцип "выделение ресурса есть инициализация". Для этого можно создать класс, конструктор которого будет открывать файл, а в деструкторе файл будет закрываться. При начале работы с файлом пользователь должен создать объект этого класса. При этом файл будет автоматически открыт конструктором класса. В случае генерации исключения при работе приложения объект будет уничтожен и при этом неизбежно будет вызван его деструктор, который и закроет файл. Если исключение не будет сгенерировано и работа программы завершится нормально, то и в этом случае пользователю не придется заботится о явном закрытии файла, так как созданный им объект будет автоматически уничтожен при выходе из области видимости и файл будет закрыт деструктором класса. class FileOpen { FILE* pf; public: FileOpen(char* filename, char* mode) { if ((pf = fopen(filename, mode)) == NULL) { //вывести сообщение о том, что файл открыть //не удалось } } ~FileOpen() { fclose(pf); } //... };