Правила программирования на Си и Си++

       

По возможности возбуждайте объекты типа error


Листинг 15 показывает простую систему определений класса для возбуждения исключений. Я могу перехватить ошибки чтения или записи подобным образом:

try

{

    file f("name", "rw");

    buffer b;

    b = f.read();

    f.write( b );

}

catch( file::open_error r )

{

    // Файл не существует или не может быть открыт.

}

catch( file::io_error r )



{

    // Какая-то из неисправимых ошибок ввода/вывода.

}

Если меня волнует лишь то, что произошла ошибка определенного вида, и не волнует, какого конкретно, то я могу сделать так:

file f;

try

{

    buffer b;

    b = f.read()

    f.write( b );

}

catch( file::error r )

{

    // ...

}

Листинг 15. Классы исключений

class file

{

public:

     class error {};

     class open_error : public error {};

     class io_error : public error {};

/p>

     // ...

}

Этот код работает, потому что объект file::read_error

является объектом типа file::error

(так как относится к производному классу). Вы всегда можете перехватить объект производного класса, используя ссылку или указатель базового класса.

Я мог бы также предложить другой класс, использующий тот же самый механизм:

class long_double

{

public:

   class error {};

   class didvide_by_zero : public error {};

   // ...

};

Так как классы error являются вложенными определениями, то именами на самом деле являются file::error и long_double::error, поэтому здесь нет конфликта имен.

Для упрощения сопровождения я всегда использую error в качестве своего базового класса для исключений. (Я не мог использовать производный класс, даже если здесь был бы возможен всего один вид ошибки). Таким образом, я знаю, что, имея возбуждающий исключение класс some_class, можно перехватить это исключение при помощи:

catch(some_class::error r)

Эту ошибку искать не придется. Если применяется наследование, то я использую базовый класс error

таким образом:

class employee

{

public:

   class error                                {};

   class database_access_error : public error {};

};

class peon : public employee

{

   class error : public employee::error {};

   class aagh  : public error           {};

};

Этим способом исключение aagh

может быть перехвачено как peon::aagh, peon::error

или employee::error.

Нет смысла создавать класс глобального уровня error, от которого наследуются все локальные классы error, потому что для обработки этой ситуации вы можете использовать обработчик catch(…).



Содержание раздела