Титульная страница   Пространства имен   Иерархия классов   Алфавитный указатель   Классы   Файлы   Члены пространства имен   Члены классов   Члены файла  

ceexample.cpp

См. документацию.
00001 /*
00002  * Copyright (C) Sergey P. Derevyago, 2003-2004.
00003  *
00004  * Permission to copy, use, modify, sell and distribute this software is granted
00005  * provided this copyright notice appears in all copies.
00006  * This software is provided "as is" without express or implied warranty, and
00007  * with no claim as to its suitability for any purpose.
00008  *
00009  */
00010 
00016 #include <stdio.h>
00017 #include <vector>
00018 #include "cexception.hpp"
00019 
00020 using namespace std;
00021 
00023 class ExampleCException : public CException {
00024  protected:
00025       ExampleCException(const FileLine& loc, const std::string& msg,
00026         sh_ptr<CException> nest) : CException(loc, msg, nest) {}
00027 
00028  public:
00029       friend sh_ptr<CException> newExampleCException(const FileLine& loc,
00030         const std::string& msg, sh_ptr<CException> nest=sh_ptr<CException>());
00031 
00032       virtual std::string getClassName() const { return "ExampleCException"; }
00033 };
00034 
00035 inline sh_ptr<CException> newExampleCException(const CException::FileLine& loc,
00036   const std::string& msg, sh_ptr<CException> nest)
00037 {
00038 #ifndef DERS_RETHROW_BUG
00039  // обычная версия тела функции
00040  return sh_ptr<CException>(new ExampleCException(loc, msg, nest));
00041 #else
00042  // версия для компиляторов, некорректно обрабатывающих перевозбуждение
00043  // исключений
00044  // в этом случае возбуждаемое исключение следует сохранять в переменной
00045  // CException::current, чтобы функция toCException() смогла впоследствии
00046  // получить (последнее возбужденное) исключение не перевозбуждая его
00047  return CException::current=sh_ptr<CException>(new ExampleCException(loc, msg,
00048    nest));
00049 #endif 
00050 }
00051 
00052 int i;
00053 
00054 void g()
00055 {
00056  // использование собственного блока try вокруг тела "сложной" функции является
00057  // хорошо зарекомендовавшей себя практикой, а если в спецификации функии
00058  // написано, что она возбуждает только CException, то без этого просто не
00059  // обойтись
00060  try {
00061      switch (i) {
00062  // возбуждаем наше ExampleCException с помощью функции newExampleCException()
00063  // макрос _FLINE_ заменяет громоздкое CException::FileLine(__FILE__, __LINE__)
00064             case 1: throw newExampleCException(_FLINE_, "Hello from g()");
00065  // неявно возбуждаем std::out_of_range путем доступа за пределы массива
00066             case 2: {
00067                  vector<int> v;
00068                  v.at(0);
00069             }
00070  // явно возбуждаем исключение типа int
00071             case 3: throw 3;
00072      }
00073  }
00074  // единственный блок catch, перехватывающий все исключения
00075  // т.к. используется формат (...), тип перехваченного исключения теряется, тем
00076  // не менее, функция toCException() перевозбуждает исключение, определяет его
00077  // тип и возвращает нам в виде sh_ptr<CException>
00078  // далее это восстановленное исключение передается в качестве nested новому
00079  // исключению, содержащему сообщение о проблеме в функции g()
00080  catch (...) {
00081        throw newCException(_FLINE_, "Problems in g()", toCException(_FLINE_));
00082  }
00083 }
00084 
00085 void f()
00086 {
00087  try { g(); }
00088  // аналогично, перехватываем все исключения и сообщаем о проблеме в функции f()
00089  catch (...) {
00090        throw newCException(_FLINE_, "Problems in f()", toCException(_FLINE_));
00091  }
00092 }
00093 
00094 int main()
00095 {
00096  for (i=1; i<=4; i++) {
00097      try {
00098          if (i<4) f();
00099  // возбуждаем "неизвестное исключение" прямо из этого блока, чтобы показать
00100  // зачем функция toCException() также принимает параметр CException::FileLine
00101          else throw 4;
00102      }
00103  // перехватываем возникшие исключения и используем toStringAll() для вывода
00104  // полной информации о всей цепочке исключений
00105      catch (...) {
00106            printf("\tException #%d:\n%s", i,
00107              toCException(_FLINE_)->toStringAll().c_str());
00108      }
00109  }
00110 }

Документация по ftext. Последние изменения: Sat Mar 20 17:58:15 2004. Создано системой doxygen1.3