19 Ocak 2018 Cuma

throw ile Exception'ı Tekrar Fırlatma

Giriş
Exception yakalandıktan sonra tekrar fırlatılabilir. Aslında bu yetenek gördüğüm tüm programlama dillerinde var. Yakalama kodu içinde exception değiştirilse bile sorun olmaz.
try {
    foo();
} catch (bar& ex){
    ex.addSomeMoreInformation(...);
    throw;
}
Exception kodunu ortak yapmak için Lippincott yöntemi kullanılır. Şöyle yaparız.
void Lippincott () noexcept {
  try {
    throw;
  } catch (const std::out_of_range& e) {
    show_msg("Out of range error", e.what());
  } catch (const std::logic_error& e) {
    show_msg("Logic error", e.what());
  } catch (const std::system_error& e) {
    show_msg("System error", e.what());
  } catch (const std::runtime_error& e) {
    show_msg("Runtime error", e.what());
  } catch (const std::exception& e) {
    show_msg("Generic error", e.what());
  }
}

void func1() noexcept {
  try {
    do_task();
    do_another_task();
  } catch (...) {
    Lippincott();
  }
}

void func2() noexcept {
  try {
    do_something();
    do_something_else();
    do_even_more();
  } catch (...) {
    Lippincott();
  }
}
Fırlatacak Exception Yoksa
Eğer fırlatılacak exception yoksa std::terminate çağrılır.
If no exception is presently being handled, executing a throw-expression with no operand calls std::terminate().
Örnek
Aşağıda görülebilir.
int main()
{
  try{
  cout<<"try";
  throw ;
  }
  catch(...){
    cout<<"catch";
  }
  return 0;
}
Örnek
Elimizde şöyle bir kod olsun.
class A
{
public:
    A()
    {
        std::cout << "A" << std::endl;
    }

    ~A()
    {
        std::cout << "~A" << std::endl;
    }
};

void f()
{
    A a;
    throw;
}

void g()
{
    try
    {
        f();
    }
    catch(...)
    {
        std::cout << "Caught" << std::endl;
    }
}
Çıktı olarak std::terminate çağrıldığı için şunu alırız.
A
~A

This application has requested the Runtime to terminate it in an unusual way.
Please contact the application's support team for more information.

Hiç yorum yok:

Yorum Gönder