Site Tools


c_exception

Вызов исключения

  class Error{
  public:
      Error(){
          cout << "This Error" << endl;
      }
  };
  
  class MyClass{
  public:
      MyClass(int i){
          if(i < 50){
              cout << i << endl;
          }else{
              throw Error();
          }
      }
  };
  
  int main(int argc, char *argv[])
  {
      MyClass(30);
      MyClass(99);
      MyClass(31);
      cout << "Normal end programm" << endl;
  }

Вывод:

30
This Error
terminate called after throwing an instance of 'Error'
The program has unexpectedly finished.

Ловить исключения с использованием try, catch

  class Error{
  public:
      Error(){
          cout << "This Error" << endl;
      }
  };
  
  class MyClass{
  public:
      MyClass(int i){
          if(i < 50){
              cout << i << endl;
          }else{
              throw Error();
          }
      }
  };
  
  int main(int argc, char *argv[])
  {
      try{ // ловим
          MyClass(30);
          MyClass(99);
          MyClass(31);
      }catch(Error){
          cout << "in catch" << endl;
      }
      cout << "Normal end programm" << endl;
  }

вывод:

30
This Error
in catch
Normal end programm

Ловим несколько разных исключений

  ...
  }catch(Error){
      cout << "catch" << endl;
  }catch(ErrorTwo){
      cout << "second catch" << endl;
  }
  ...

Ловим любое исключение

catch(...){}
  class Error{
  public:
      Error(){
          cout << "This Error" << endl;
      }
  };
  
  class SecondError{
  public:
      SecondError(){
          cout << "This Second Error" << endl;
      }
  };
  
  
  class MyClass{
  public:
      MyClass(int i){
          if(i < 50){
              cout << i << endl;
          }else if(i < 100){
              throw Error();
          }else{
              throw SecondError();
          }
      }
  };
  
  int main(int argc, char *argv[])
  {
      try{
          MyClass(29);
          MyClass(111);
          MyClass(98);
      }catch(Error){
          cout << "catch" << endl;
      }catch(...){
          cout << "Another catch" << endl;
      }
      cout << "Normal end programm" << endl;
  }

вывод:

29
This Second Error
Another catch
Normal end programm

указание(перечисление) допустимых исключений

Можно указывать как для функций, так и для методов.

class Error{
public:
    Error(){
        cout << "This Error" << endl;
    }
};

class SecondError{
public:
    SecondError(){
        cout << "This Second Error" << endl;
    }
};


class MyClass{
public:
    MyClass(int i) throw(Error){ // тут мы указываем, что возможно только исключение Error()
        if(i < 50){
            cout << i << endl;
        }else if(i < 100){
            throw Error();
        }else{
            throw SecondError(); // ошибки компиляции при включение других исключений не происходит, но они не обрабатываются catch
        }
    }
};

int main(int argc, char *argv[])
{
    try{
        MyClass(29);
        MyClass(111);
        MyClass(98);
    }catch(Error){
        cout << "catch" << endl;
    }catch(...){
        cout << "Another catch" << endl;
    }
    cout << "Normal end programm" << endl;
}

вывод:

29
This Second Error
terminate called after throwing an instance of 'SecondError'
The program has unexpectedly finished.

throw string

позволяет не создовать дополнительные классы + передает информацию об ошибке.

class MyClass{
public:
    MyClass(int i){
        if(i < 50){
            cout << i << endl;
        }else{
            throw string("this info about error");
        }
    }
};

int main(int argc, char *argv[])
{
    try{
        MyClass(41);
        MyClass(98);
        MyClass(111);
    }catch(string x){
        cout << "catch string: " << x << endl;
    }
    cout << "Normal end programm" << endl;
}

вывод:

41
catch string: this info about error
Normal end programm

exception in std::

  #include <iostream>
  #include <vector>
  using namespace std;
  
  int main(int argc, char *argv[]){
      vector<int> testVector;
      try{
          while(1){
              testVector.push_back(1);
          }
      }catch(std::exception &errorObj){  //все исключения наследуют интерфейс std::exception c методом .what()
          cout << "We catch error: " << errorObj.what() << endl;
  
      }catch(...){
          cout << "We catch error: unknow" << endl;
      }
  }

exception в конструкторе

Если исключение возникает в конструкторе и выходит из него, то деструктор, понятное дело, не вызывется.

  #include <exception>
  
  using namespace std;
  
  class Base
  {
  private:
      vector<int> testVector;
  
  public:
      Base()
      {
          std::cout << "Hello from Base()" << std::endl;
          while(1){
              testVector.push_back(1);
          }
      }
  
      virtual ~Base()
      {
          std::cout << "Hello from ~Base()" << std::endl;
          // Здесь мы планировали очищать выделенные ресурсы
      }
  };
  
  
  int main(int argc, char** arg){
      try
      {
          Base b;
      }
      catch(const std::exception &e)
      {
          std::cout << "Exception message: " << e.what() << std::endl;
      }
  }

вывод:

Hello from Base()
Exception message: std::bad_alloc

Если необходимо освобождать ресурсы выделяемые в конструкторе, то придется делать это в catch или использовать умный указатель

пример решения exception в конструкторе

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

  class Base
  {
  private:
      class CHandle
      {
      public:
          ~CHandle()
          {
              delete m_handle;
              cout << "we deleted m_handle" << endl;
          }
      private:
          int* m_handle;
      public:
          // Для полноценного smart pointer'а перегрузки одной операции
          // не достаточно, но для нашего примера и понимания вполне хватит
          void operator = (int* handle)
          {
              m_handle = handle;
          }
      };
  
      CHandle m_hFile;
  
  public:
      Base()
      {
          std::cout << "Hello from Base()" << std::endl;
          m_hFile = new int(5);
          // Вызываем код, который в ходе своего выполнения бросает исключение
          vector<int> testVector;
          while(1){
              testVector.push_back(1);
          }
      }
  
      virtual ~Base()
      {
          std::cout << "Hello from ~Base()" << std::endl;
      }
  };
  
  
  int main(int argc, char** arg){
      try
      {
          Base b;
      }
      catch(const std::exception &e)
      {
          std::cout << "Exception message: " << e.what() << std::endl;
      }
  }

вывод:

Hello from Base()
we deleted m_handle
Exception message: std::bad_alloc

throw без параметров в коде

неперехватывается и следовательно вызывает terminate

  class MyClass{
  public:
      MyClass(int i){
          if(i < 50){
              cout << i << endl;
          }else{
              throw;
          }
      }
  };
  
  int main(int argc, char *argv[])
  {
      try{
          MyClass(41);
          MyClass(98);
          MyClass(111);
      }catch(string x){
          cout << "catch string: " << x << endl;
      }catch(...){
          cout << "always catch this and thow next" << endl;
      }
      cout << "Normal end programm" << endl;
  }

вывод

41
terminate called without an active exception
The program has unexpectedly finished.

throw без параметров при повторном вызове

“перевозбуждает” предыдущий вызов (повторно, с теме же параметрами).

  class MyClass{
  public:
      MyClass(int i){
          if(i < 50){
              cout << i << endl;
          }else{
              throw string("this info about error");
          }
      }
  };
  
  int main(int argc, char *argv[])
  {
      try{
          MyClass(41);
          MyClass(98);
          MyClass(111);
      }catch(string x){
          cout << "catch string: " << x << endl;
          try{
              throw;
          }catch(string strIn){
              cout << "again catch string throw, but now without parametrs" << endl;
          }catch(...){
              cout << "again catch throw" << endl;
          }
      }catch(...){
          cout << "always catch this and thow next" << endl;
      }
      cout << "Normal end programm" << endl;
  }

вывод:

41
catch string: this info about error
again catch string throw, but now without parametrs
Normal end programm

tmp

You could leave a comment if you were logged in.
c_exception.txt · Last modified: 2013/04/09 13:38 by konovalov

Page Tools