Обработка исключений Основы метапрограммирования
2 Способы обработки ошибок 1.Игнорировать 2.Выводить сообщение 3.Возвращать bool 4.Возвращать int 5.Assert 6.Try/Catch
3 #include int x=0, y=0; std::cin >> x >> y; assert(y != 0); int z = x / y; Assert (c-style)
4 void f1() {/* тут могут возникнуть ошибки */} void f2() {/* тут могут возникнуть ошибки */} void f3() {/* тут могут возникнуть ошибки */} int main() { f1(); f2(); f3(); // >>> Как обработать все ошибки здесь?
5 Система обработки исключительных ситуаций: предназначена для обработки стандартных и пользовательских исключений позволяет обрабатывать ошибки не в том месте, где они возникли не предполагает дальнейшее выполнение программы try { // код, где возможно исключение } catch(std::exception& ex) { // обработчик исключения } Try/Catch
6 try { double* p = new double[ ]; } catch(const std::bad_alloc& ex) { std::cerr
7 exception logic_errorruntime_error length_error domain_error out_of_range invalid_argument bad_alloc bad_exception io_base::failure bad_typeid bad_cast range_error overflow_error underflow_error Стандартные классы исключений
8 try { if (y == 0) throw std::string("Деление на ноль!"); z = x / y; } catch(const std::string& ex) { std::cerr
9 try { if (y == 0) throw std::exception("Деление на ноль!"); z = x / y; } catch(std::exception& ex) { std::cerr
10 class ExceptionDivideByZero : public std::exception { }; try { if (y == 0) throw ExceptionDivideByZero(); z = x / y; } catch(ExceptionDivideByZero) { std::cerr
11 Catch all try { } catch(...) { std::cerr
12 Catch-цепочка try { } catch(std::bad_alloc) { } catch(std::bad_cast) { }
13 try { } catch(std::exception) { } catch(...) { } catch(std::bad_alloc) { } // ОШИБКА
14 try { } catch(std::bad_alloc) { } catch(std::exception) { } catch(...) { } // ВЕРНО
15 Повторное выбрасывание исключения try { try { // Здесь произошла ошибка выделения памяти } catch(std::bad_alloc) { // Выдаем сообщение, и перевыбрасываем: throw; } catch(std::exception) { // Заносим в лог }
16 Конструктор При выбросе исключения в конструкторе процесс конструирования экземпляра класса прерывается и он считается не созданным. Деструктор для такого класса вызван не будет. Будут вызваны деструкторы для тех полей класса, для которых успели выполниться конструкторы. Деструктор Деструкторы не должны возвращать исключений. Если в деструкторе возникает исключение, оно должно быть обработано в нем же.
17 class B { public: B() { std::cout
18 Существует 2 разновидности шаблонов: 1)Шаблоны функций. 2)Шаблоны классов. Простое понимание: шаблоны – это универсальные классы и функции, которые работают для любого типа данных. Глубокое понимание: шаблон это указания компилятору правил по созданию классов во время компиляции. Иными словами, это код, результатом компиляции которого является другой код. Шаблоны
19 Шаблоны функций. Шаблон функции – обобщенная функция, определяющая некую универсальную совокупность операций. int min ( int a, int b ) { return (a < b ? a : b); }
20 int min ( int a, int b ) { return (a < b ? a : b); } float min ( float a, float b ) { return (a < b ? a : b); } double min ( double a, double b ) { return (a < b ? a : b); }
21 template T Min (T a, T b) { return ( a < b ? a : b ); } int minXY = Min (3, 5); int minXY = Min (3.0, 5.0);
22 int x=1,y=3; Swap(x, y); // конкретизация для int std::сout
23 template T Sum (const T & one, const T & two) { return (one + two); } Sum(10, 20.0); //ОШИБКА 1) Типовое соответствие Синтаксические правила 0) Объявление и реализация в h-файле
24 template void f (T1 a, T2 b) { …… } 2) Используемые в заголовке функции типы должны присутствовать в заголовке шаблона.
25 template void f (T1 a) { …….. } 3) Каждый типовой параметр шаблона должен появиться в списке формальных параметров функции. Иначе потребуется явная конкретизация. f (1);
26 Явная конкретизация типа template T Sum(T left, T right) { return (left + right); } void main() { char x = 1, y = 2; //std::cout
27 template T & Max (const T & a, const T & b) { return ( a > b ? a : b ); } const char * Max (const char *strA, const char * strB) { return ( strcmp (strA, strB) >= 0 ? strA : strB ); } std::cout
28 Алгоритм разрешения ссылки при вызове функции: 1) найти функцию с точно такими параметрами. 2) если нет - найти шаблонную, порождение которой точно соответствует по параметрам. 3) если нет – поиск обычной, параметры которой можно преобразовать.
29 Шаблоны классов - Шаблон класса описывается подобно обычному классу, но имеет типовой параметр, уточнение которого происходит на стадии компиляции (инстанцирование). - Это позволяет создавать универсальные структуры данных (массив, список, очередь, стек,....) и реализовывать универсальные алгоритмы работы с ними. - Одно из применений данной возможности в классе – хранение и обработка объектов любого типа. Такие классы называются контейнерами. Шаблон класса – это некое общее описание класса, на основе которого создаются его версии для различных типов данных.
30 template class vector { T* data; public: vector(); ~vector(); T & operator [] (int index); }; Шаблон массива vector vec; for(int i=0; i
31 template class vector { T data [Size]; public: vector(); T & operator [] ( int index ); }; Нетиповые параметры шаблона Шаблон одномерного статического массива. Размер – параметр шаблона.
32 template vector :: vector() { for(int n=0; n < Size; n++) data[n] = T(); } template T & vector ::operator [] ( int index ) { return data[index]; }
33 vector vecNumbers; //конкретизация для int vector vecTimes; //конкретизация для класса
34 template class vector { T * data; public: vector (int size); ~vector(); }; template vector :: vector (int size) { data = new T [size]; for(int i=0; i < size; i++) data[n] = T(); } Параметры конструктора vector vec (100);
35 template class Stack { T data [Size]; int top; public: Stack(); void Push(T item); T Pop(); }; Шаблон класса стека top 0Size-1 data
36 template Stack ::Stack() { top = 0; } template void Stack ::Push(T item) { if(top >= Size) { assert(false); } data [top++] = item; } template T Stack ::Pop() { if(top
Stack st; for(int i=0; i
38 Специализация шаблонов (полная) template //универсальный шаблон class vector { T* values; public: vector(); }; template class vector //шаблон для типа int { int* values; public: vector(); };
39 template int Fact() { return n * Fact (); } template int Fact () { return 1; } int main() { int f = Fact (); return 0; } Шаблон рекурсивного вычисления факториала
40 template struct COMPILE_ASSERT_STRUCT { }; template struct COMPILE_ASSERT_STRUCT { virtual void dummy() = 0; }; #define COMPILE_ASSERT(cond) COMPILE_ASSERT_STRUCT (); void main() { const int x = 1; COMPILE_ASSERT(x > 0); }