error.h.xml 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177
  1. <chapter xml:id="error.h">
  2. <title><tt>__vic/error.h</tt></title>
  3. <p>Инструменты обработки ошибок.</p>
  4. <chapter xml:id="exception">
  5. <title><tt>exception</tt></title>
  6. <code-block lang="C++">
  7. class exception : public std::exception
  8. {
  9. public:
  10. exception();
  11. explicit exception(const char *message);
  12. const char *what() const noexcept;
  13. protected:
  14. void set_message(const char *message);
  15. };
  16. </code-block>
  17. <p>Небольшое расширение <tt>std::exception</tt> - объект хранит сообщение об
  18. ошибке, переданное в конструкторе, которое потом возвращает <tt>what()</tt>.
  19. Может быть использован как базовый или конкретный класс исключения. Не
  20. использует и не зависит от <tt>std::string</tt>, в отличие от
  21. <tt>std::logic_error</tt> и <tt>std::runtime_error</tt>. Также Вам нет нужды
  22. решать, какое из последних следует использовать в каждом конкретном случае.</p>
  23. <section><title>Члены класса</title>
  24. <synopsis>
  25. <prototype>exception()</prototype>
  26. <p>Создаёт объект с пустым сообщением об ошибке.</p>
  27. </synopsis>
  28. <synopsis>
  29. <prototype>explicit exception(const char *message)</prototype>
  30. <p>Создаёт объект с указанным сообщением об ошибке.</p>
  31. </synopsis>
  32. <synopsis>
  33. <prototype>const char *what() const noexcept</prototype>
  34. <p>Возвращает установленное ранее сообщение.</p>
  35. </synopsis>
  36. <synopsis>
  37. <prototype>void set_message(const char *message)</prototype>
  38. <p>Устанавливает новое сообщение.</p>
  39. </synopsis>
  40. </section>
  41. <section><title>Пример</title>
  42. <code-block lang="C++">
  43. struct custom_exception : public __vic::exception
  44. {
  45. explicit custom_exception(const char *msg) : __vic::exception(msg) {}
  46. };
  47. throw custom_exception("Error condition description");
  48. </code-block>
  49. </section>
  50. </chapter>
  51. <chapter xml:id="libc_error">
  52. <title><tt>libc_error</tt></title>
  53. <code-block lang="C++">
  54. class libc_error : public std::exception
  55. {
  56. public:
  57. explicit libc_error(int err_no = errno);
  58. explicit libc_error(const char *prompt, int err_no = errno);
  59. const char *what() const noexcept;
  60. int code() const;
  61. int get_errno() const;
  62. };
  63. </code-block>
  64. <p>Класс предназначен для замены стандартного механизма обработки ошибок
  65. в мире C - <tt>errno</tt> - на механизм исключений. Также класс пригоден для
  66. использования в многопоточных приложениях вместо не всегда реентерабельного
  67. вызова <tt>std::strerror()</tt>.</p>
  68. <p>Ниже приведён фрагмент кода, типичный для языка C:</p>
  69. <code-block lang="C">
  70. // C:
  71. int fd;
  72. if((fd = open("qqqq", O_RDONLY)) == -1)
  73. {
  74. perror("open");
  75. if(errno == ENOENT) exit(1);
  76. }
  77. </code-block>
  78. <p>Если файл не найден, программа напечатает</p>
  79. <tty>
  80. open: No such file or directory
  81. </tty>
  82. <p>в <tt>stderr</tt> и выйдет, вернув в ОС значение <tt>1</tt>.</p>
  83. <p>Какие проблемы присущи этому коду? Во-первых, не у каждой программы есть
  84. <tt>stderr</tt>, поэтому библиотечная функция не может сама выводить туда
  85. сообщения об ошибках. Во-вторых, значение глобальной переменной <tt>errno</tt>
  86. может быть затёрто любым следующим вызовом, если его не сохранить. В-третьих,
  87. решение о завершении процесса должна принимать конечная программа. Обычная
  88. библиотечная функция не может брать на себя такие полномочия. В-четвёртых,
  89. в общем случае программа на С++ не может вызывать <tt>std::exit()</tt>, так
  90. как не будут вызваны деструкторы активных объектов, что может разрушить логику
  91. работы программы.</p>
  92. <p>Ниже приведён адаптированный пример для C++ с использованием описываемого
  93. класса:</p>
  94. <code-block lang="C++"><![CDATA[
  95. // C++:
  96. try
  97. {
  98. int fd = open("qqqq", O_RDONLY);
  99. if(fd == -1) throw __vic::libc_error("open");
  100. // or just
  101. // if(fd == -1) throw __vic::libc_error();
  102. }
  103. catch(const __vic::libc_error &ex)
  104. {
  105. std::cerr << ex.what() << '\n';
  106. if(ex.code() == ENOENT) return 1;
  107. }
  108. ]]></code-block>
  109. <p>Как видно, функция просто корректно отслеживает ошибочную ситуацию и
  110. сообщает о ней вызывающей среде. Далее вызывающая сторона уже сама может
  111. принять решение об обработке ошибки. В простейшем случае она поступает также
  112. как предыдущая C-программа: печатает сообщение в стандартный поток вывода
  113. ошибок и завершает выполнение. Кроме того, код ошибки надёжно сохранён в
  114. исключении и ни кем не перетрётся.</p>
  115. <note>Обычно исключения данного класса не должны бросаться явно! Используйте
  116. <xref to="throw_errno"/> для их генерации.</note>
  117. <section><title>Члены класса</title>
  118. <synopsis>
  119. <prototype>explicit libc_error(int err_no = errno)</prototype>
  120. <p><tt>err_no</tt> - код ошибки.</p>
  121. <postcondition><tt>code() == err_no</tt></postcondition>
  122. </synopsis>
  123. <synopsis>
  124. <prototype>explicit libc_error(const char *prompt, int err_no = errno)</prototype>
  125. <p><tt>prompt</tt> - заголовок выводимого сообщения. Параметр имеет такой же
  126. смысл, как и параметр <tt>std::perror()</tt>.</p>
  127. </synopsis>
  128. <synopsis>
  129. <prototype>const char *what() const noexcept</prototype>
  130. <p>Возвращает описание ошибки в формате <tt>std::perror()</tt>.</p>
  131. </synopsis>
  132. <synopsis>
  133. <prototype>int code() const</prototype>
  134. <prototype>int get_errno() const</prototype>
  135. <p>Возвращает хранимый код ошибки.</p>
  136. </synopsis>
  137. </section>
  138. </chapter>
  139. </chapter>