'

Обработка исключений Основы метапрограммирования

Понравилась презентация – покажи это...





Слайд 0

Обработка исключений Основы метапрограммирования


Слайд 1

2 Способы обработки ошибок Игнорировать Выводить сообщение Возвращать bool Возвращать int Assert Try/Catch


Слайд 2

3 #include <cassert> int x=0, y=0; std::cin >> x >> y; assert(y != 0); int z = x / y; Assert (c-style)


Слайд 3

4 void f1() {/* тут могут возникнуть ошибки */} void f2() {/* тут могут возникнуть ошибки */} void f3() {/* тут могут возникнуть ошибки */} int main() { f1(); f2(); f3(); // >>> Как обработать все ошибки здесь? <<< return 0; } Недостатки


Слайд 4

5 Система обработки исключительных ситуаций: предназначена для обработки стандартных и пользовательских исключений позволяет обрабатывать ошибки не в том месте, где они возникли не предполагает дальнейшее выполнение программы try { // код, где возможно исключение } catch(std::exception& ex) { // обработчик исключения } Try/Catch


Слайд 5

6 try { double* p = new double[2000000000]; } catch(const std::bad_alloc& ex) { std::cerr << ex.what(); } //------------------------------------------------ try { double* p = new double[2000000000]; } catch(std::bad_alloc) { } Bad_alloc


Слайд 6

7 exception logic_error runtime_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 Стандартные классы исключений


Слайд 7

8 try { if (y == 0) throw std::string("Деление на ноль!"); z = x / y; } catch(const std::string& ex) { std::cerr << ex; } Выбрасывание исключения (throw) Вариант 1: использовать простой тип


Слайд 8

9 try { if (y == 0) throw std::exception("Деление на ноль!"); z = x / y; } catch(std::exception& ex) { std::cerr << ex.what(); } Вариант 2: класс std::exception


Слайд 9

10 class ExceptionDivideByZero : public std::exception { }; try { if (y == 0) throw ExceptionDivideByZero(); z = x / y; } catch(ExceptionDivideByZero) { std::cerr << "Деление на ноль!"; } Вариант 3: собственный класс


Слайд 10

11 Catch all try { } catch(...) { std::cerr << "Неизвестная ошибка!"; }


Слайд 11

12 Catch-цепочка try { } catch(std::bad_alloc) { } catch(std::bad_cast) { }


Слайд 12

13 try { } catch(std::exception) { } catch(...) { } catch(std::bad_alloc) { } // ОШИБКА


Слайд 13

14 try { } catch(std::bad_alloc) { } catch(std::exception) { } catch(...) { } // ВЕРНО


Слайд 14

15 Повторное выбрасывание исключения try { try { // Здесь произошла ошибка выделения памяти } catch(std::bad_alloc) { // Выдаем сообщение, и перевыбрасываем: throw; } } catch(std::exception) { // Заносим в лог }


Слайд 15

16 Конструктор При выбросе исключения в конструкторе процесс конструирования экземпляра класса прерывается и он считается не созданным. Деструктор для такого класса вызван не будет. Будут вызваны деструкторы для тех полей класса, для которых успели выполниться конструкторы. Деструктор Деструкторы не должны возвращать исключений. Если в деструкторе возникает исключение, оно должно быть обработано в нем же.


Слайд 16

17 class B { public: B() { std::cout << "1"; } ~B() { std::cout << "2"; } }; class C { B b; public: C() { throw 0; std::cout << "3"; } ~C() { std::cout << "4"; } }; ------------------------ try { C c; } catch(...) { }


Слайд 17

18 Существует 2 разновидности шаблонов: Шаблоны функций. Шаблоны классов. Простое понимание: шаблоны – это универсальные классы и функции, которые работают для любого типа данных. Глубокое понимание: шаблон — это указания компилятору правил по созданию классов во время компиляции. Иными словами, это код, результатом компиляции которого является другой код. Шаблоны


Слайд 18

19 Шаблоны функций. Шаблон функции – обобщенная функция, определяющая некую универсальную совокупность операций. int min ( int a, int b ) { return (a < b ? a : b); }


Слайд 19

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); }


Слайд 20

21 template <class T> T Min (T a, T b) { return ( a < b ? a : b ); } int minXY = Min (3, 5); int minXY = Min (3.0, 5.0);


Слайд 21

22 int x=1,y=3; Swap(x, y); // конкретизация для int std::сout << x << " " << y << std::endl; template <class T> void Swap(const T & a, const T & b) { T tmp; tmp = a; a = b; b = tmp; } Шаблонная функция обмена 2-х значений.


Слайд 22

23 template <class T> T Sum (const T & one, const T & two) { return (one + two); } Sum(10, 20.0); //ОШИБКА 1) Типовое соответствие Синтаксические правила 0) Объявление и реализация в h-файле


Слайд 23

24 template <class T1> void f (T1 a, T2 b) { …… } 2) Используемые в заголовке функции типы должны присутствовать в заголовке шаблона.


Слайд 24

25 template <class T1, class T2> void f (T1 a) { …….. } 3) Каждый типовой параметр шаблона должен появиться в списке формальных параметров функции. Иначе потребуется явная конкретизация. f<int, int>(1);


Слайд 25

26 Явная конкретизация типа template <class T> T Sum(T left, T right) { return (left + right); } void main() { char x = 1, y = 2; //std::cout << Sum(x,y); //будет выведен символ std::cout << Sum <int> (x,y); //char преобразуется в int }


Слайд 26

27 template <class T> 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 << Max (1, 5) << std::endl; std::cout << Max («aa», «ba») << std::endl; Специализация шаблонной функции Реализация шаблонной функции для конкретного типа замещает, маскирует шаблон (для этого типа).


Слайд 27

28 Алгоритм разрешения ссылки при вызове функции: 1) найти функцию с точно такими параметрами. 2) если нет - найти шаблонную, порождение которой точно соответствует по параметрам. 3) если нет – поиск обычной, параметры которой можно преобразовать.


Слайд 28

29 Шаблоны классов - Шаблон класса описывается подобно обычному классу, но имеет типовой параметр, уточнение которого происходит на стадии компиляции (инстанцирование). - Это позволяет создавать универсальные структуры данных (массив, список, очередь, стек,....) и реализовывать универсальные алгоритмы работы с ними. - Одно из применений данной возможности в классе – хранение и обработка объектов любого типа. Такие классы называются контейнерами. Шаблон класса – это некое общее описание класса, на основе которого создаются его версии для различных типов данных.


Слайд 29

30 template <class T> class vector { T* data; public: vector(); ~vector(); T & operator [] (int index); }; Шаблон массива vector<int> vec; for(int i=0; i<10; i++) a[i] = i+1;


Слайд 30

31 template <class T, int Size> class vector { T data [Size]; public: vector(); T & operator [] ( int index ); }; Нетиповые параметры шаблона Шаблон одномерного статического массива. Размер – параметр шаблона.


Слайд 31

32 template <class T, int Size> vector <T, Size>:: vector() { for(int n=0; n < Size; n++) data[n] = T(); } template <class T, int Size> T & vector <T, Size>::operator [] ( int index ) { return data[index]; }


Слайд 32

33 vector <int,10> vecNumbers; //конкретизация для int vector <Time,100> vecTimes; //конкретизация для класса


Слайд 33

34 template <class T> class vector { T * data; public: vector (int size); ~vector(); }; template <class T> vector <T>:: vector (int size) { data = new T [size]; for(int i=0; i < size; i++) data[n] = T(); } Параметры конструктора vector <int> vec (100);


Слайд 34

35 template <class T, int Size> class Stack { T data [Size]; int top; public: Stack(); void Push(T item); T Pop(); }; Шаблон класса стека


Слайд 35

36 template <class T, int Size> Stack <T,Size>::Stack() { top = 0; } template <class T, int Size> void Stack <T,Size>::Push(T item) { if(top >= Size) { assert(false); } data [top++] = item; } template <class T, int Size> T Stack<T,Size>::Pop() { if(top <= 0) { assert(false); } return data[--top]; }


Слайд 36

37 .... Stack <int, 10> st; for(int i=0; i<10; i++) st.Push(i); for(i=0; i<10; i++) std::cout << st.Pop() << " "; ..... 9 8 7 6 5 4 3 2 1 0


Слайд 37

38 Специализация шаблонов (полная) template <class T> //универсальный шаблон class vector { T* values; public: vector(); }; template <> class vector <int> //шаблон для типа int { int* values; public: vector(); };


Слайд 38

39 template <int n> int Fact() { return n * Fact<n-1>(); } template <> int Fact<0>() { return 1; } int main() { int f = Fact <5>(); return 0; } Шаблон рекурсивного вычисления факториала


Слайд 39

40 template <bool cond> struct COMPILE_ASSERT_STRUCT { }; template<> struct COMPILE_ASSERT_STRUCT<false> { virtual void dummy() = 0; }; #define COMPILE_ASSERT(cond) COMPILE_ASSERT_STRUCT<bool(cond)>(); void main() { const int x = 1; COMPILE_ASSERT(x > 0); }


×

HTML:





Ссылка: