Upgrade to Pro — share decks privately, control downloads, hide ads and more …

АФТИ ООП 2013-2014. Лекция I/11

АФТИ ООП 2013-2014. Лекция I/11

Oleg Dashevskii

December 02, 2013
Tweet

More Decks by Oleg Dashevskii

Other Decks in Education

Transcript

  1. ПЕРЕСЕЧЕНИЕ ИМЕН class Something {! public:! Something(const char *name);! //

    ...! };! Модуль Awesome class Something {! public:! Something();! // ...! };! Модуль Magic Конфликт имен классов
  2. «РЕШЕНИЕ» class AwesomeSomething {! public:! AwesomeSomething(const char *name);! // ...!

    };! ! typedef AwesomeSomething *AwesomeSomethingPtr;! ! const int AwesomeNumber = 42;! ! enum AwesomeTypes { AWESOME_FOO, AWESOME_BAR, /* ... */ };! ! void AwesomeGlobalFunction(AwesomeSomething *);
  3. ПРОСТРАНСТВА ИМЕН // awesome.h! namespace Awesome {! class Something {!

    public:! Something(const char *name);! // ...! };! ! typedef Something *SomethingPtr;! ! const int Number = 42;! ! enum Types { FOO, BAR, /* ... */ };! ! void GlobalFunction(Something *);! }! ! // awesome.cxx! #include "awesome.h"! ! Awesome::Something::Something(const char *name) {! int n = Number;! ! // ...! }! ! void Awesome::GlobalFunction(Awesome::Something *ps) {! /* ... */! } Префикс не нужен!
  4. ИСПОЛЬЗОВАНИЕ // client.cxx! #include "awesome.h"! ! ! ! void f(int

    q) {! Awesome::Something x;! int n = Awesome::Number;! ! if (q == Awesome::FOO) {! ...! }! ! Awesome::GlobalFunction(&x);! }! // client.cxx! #include "awesome.h"! ! using namespace Awesome;! ! void f(int q) {! Something x;! int n = Number;! ! if (q == FOO) {! ...! }! ! GlobalFunction(&x);! }!
  5. СОКРЫТИЕ ДЕТАЛЕЙ РЕАЛИЗАЦИИ // something.c! void public_interface_function() {! // ....!

    internal_function2();! }! ! void one_more_public_interface_function() {! internal_function1();! // ....! }! ! static void internal_function1() {! // ....! }! ! static void internal_function2() {! // ....! }
  6. ПРИВЕТ, NONAME! // something.cxx! namespace {! void internal_function1() {! //

    ....! }! ! void internal_function2() {! // ....! }! }! ! void public_interface_function() {! // ....! internal_function2();! }! ! void one_more_public_interface_function() {! internal_function1();! // ....! }
  7. ОТБОР И СЕЛЕКЦИЯ namespace His_lib {! class String { /*

    ... */ };! class Vector { /* ... */ };! }! ! namespace Her_lib {! class String { /* ... */ };! class Vector { /* ... */ };! }! ! namespace My_lib {! using namespace His_lib;! using namespace Her_lib;! ! using His_lib::String; // разрешение возможных конфликтов! using His_lib::Vector; // разрешение возможных конфликтов! ! class List { /* ... */ };! }
  8. ИСКЛЮЧЕНИЯ (EXCEPTIONS) • Сигнализирование об ошибках в C: • Код

    возврата функции. • Глобальная переменная (errno). • Можно проигнорировать! • Исключения нельзя проигнорировать! Muahahaha
  9. #include <stdio.h> ! class A { public: ~A() { puts("~A()");

    } }; ! class B { public: ~B() { puts("~B()"); } }; ! void cc() { throw 123; } ! void bb() { B b; cc(); } ! void aa() { A a; bb(); } ! int main() { try { aa(); } catch (int v) { printf("Caught %d\n", v); } } ~B() ~A() Caught 123
  10. КАК ЭТО РАБОТАЕТ • При генерации исключения с помощью throw

    начинается раскрутка стека (stack unrolling). • У всех объектов всех функций на стеке вызываются деструкторы. • Раскрутка останавливается, если найден подходящий обработчик исключения.
  11. class Matherr {};! class Overflow: public Matherr {};! class Underflow:

    public Matherr {};! class Zerodivide: public Matherr {};! ! void f() {! try {! // …суровая математика…! }! catch (Overflow) {! // обработка переполнения! }! catch (Matherr) {! // обработка любого Matherr, который не Overflow! }! }
  12. class Matherr {! virtual void debug_print() const { cerr <<

    "Математическая ошибка"; }! // ....! };! ! class Int_overflow : public Matherr {! const char *op;! int a1, a2;! public:! Int_overflow(const char *p, int a, int b) : op(p), a1(a), a2(b) {}! virtual void debug_print() const {! cerr << op << '(' << a1 << ',' << a2 << ')';! }! };! ! int add(int x, int y) {! if ((x > 0 && y > 0 && x > INT_MAX - y) || (x < 0 && y < 0 && x < INT_MIN - y))! throw Int_overflow("+", x, y);! return x+y;! }! ! void f() {! try {! g();! }! catch (Matherr &m) {! m.debug_print();! }! } Нельзя catch (Matherr m) !
  13. ПОВТОРНАЯ ГЕНЕРАЦИЯ void h() {! try {! // …! }!

    catch (Matherr) {! if (can_handle_it) { // можем полностью обработать ошибку?! // …обработка…! return;! } else {! // делаем что можем! throw; // и кидаем исключение дальше! }! }! }!
  14. ПЕРЕХВАТ ВСЕГО void h() {! try {! // ...! }!

    catch (...) {! // очистка! // ....! throw;! }! }! void process_file(const char *fn) {! FILE *fp = fopen(fn, "r");! ! try {! // работаем с файлом! }! catch (...) {! fclose(fp);! throw;! }! ! fclose(fp);! }!
  15. «ОБЕРТКА» class File_Ptr {! FILE *fp;! public:! File_Ptr(const char *fn,

    const char *access) { fp = fopen(fn, access); }! File_Ptr(FILE *fp) { this->fp = fp; }! ~File_Ptr() { if (fp) fclose(fp); }! ! operator FILE *() { return fp; }! };! ! void process_file(const char *fn) {! File_Ptr f(fn, "r");! ! // …просто используем f! // файл в любом случае будет закрыт автоматически! } «Выделение ресурса есть инициализация»
  16. ИСКЛЮЧЕНИЯ В КОНСТРУКТОРАХ • Деструктор вызывается только для полностью сконструированного

    объекта! • Если в конструкторе было исключение, то будет утечка памяти: class Y {! int *p;! void init();! public:! Y(int s) { p = new int[s]; init(); }! ~Y() { delete p; }! };
  17. ИСПОЛЬЗОВАНИЕ «ОБЕРТОК» class X {! File_Ptr fp;! Lock_Ptr lp;! public:!

    X(const char *fn, const char *lock) :! fp(fn, "rw"), // открываем файл! lp(lock) // берем блокировку! {}! };! • Сначала конструируется fp, потом lp • Если конструктор lp кидает исключение, то для fp будет вызван деструктор.
  18. BEST PRACTICES • Использовать иерархию классов исключений, не кидать int,

    
 const char * и т.п. • Делать классы исключений простыми. • Использовать исключения только для исключительных ситуаций. • Генерируя исключение, понимать где и кем оно будет обработано. • Как правило, генерация и ловля находятся в разных слоях.