2014-10-17 17 views
6

Próbuję debugować moją aplikację za pomocą wyjątków catch-rethrows. Mój kod obsługi wyjątków jest dłuższy niż niektóre bloki, które debiuję, a wszystkie są wklejane z kopią.Jak zrobić kod wyjątku DRY?

Czy istnieje lepszy sposób na wielokrotne wyrażanie poniższego kodu? Podejrzewam, że makra są tutaj, ale zwykle unikam makr takich jak dżuma.

try { 
    // Code here... 
    } 
    catch (std::exception & e) 
    { 
    ErrorMsgLog::Log("Error", "std exception caught in " __func__ " " __FILE__ " " __LINE__, e.what()); 
    throw e; 
    } 
    catch (Exception & e) 
    { 
    ErrorMsgLog::Log("Error", "Builder exception caught in " __func__ " " __FILE__ " " __LINE__, e.Message); 
    throw e; 
    } 
    catch (...) 
    { 
    ErrorMsgLog::Log("Error", "Unknown exception caught in " __func__ " " __FILE__ " " __LINE__); 
    throw std::runtime_error ("Unknown Exception in " __func__ " " __FILE__ " " __LINE__); 
    } 
+2

'dalej' wszystkie wyjątki do funkcji szablonowej? – user2485710

+4

Spraw, aby 'wyjątek' był podtypem' std :: exception', tak jak każdy normalny typ wyjątku. – rightfold

+0

1. To nie jest C++ 11. Nie można przekazać dalej. 2. Wyjątkiem jest klasa Borland C++ Builder. Poza tym, nawet gdybym tylko * potraktował wyjątek std ::, nadal chciałbym odejść od wklejenia kopii. – QuestionC

Odpowiedz

0

Najlepszym sposobem realizacji tego jest prawdopodobnie użycie makr. Definicja makra jest trochę brzydka, ale wywołanie makra będzie dość proste i nie będzie potrzeby ponownego organizowania kodu. Oto przykład, który pokazuje w jaki sposób można wdrożyć go:

#define RUN_SAFE(code) try {\ 
    code\ 
    }\ 
    catch (std::exception & e)\ 
    {\ 
    ErrorMsgLog::Log("Error");\ 
    throw e;\ 
    }\ 
    catch (Exception & e)\ 
    {\ 
    ErrorMsgLog::Log("Error");\ 
    throw e;\ 
    }\ 
    catch (...)\ 
    {\ 
    ErrorMsgLog::Log("Error");\ 
    throw std::exception();\ 
    }\ 

int main(){ 
    RUN_SAFE(
    cout << "Hello World\n"; 
) 
} 

Jeśli jesteś naprawdę nieugięty o nie za pomocą makra, można stosować metodę zaproponowaną przez @juanchopanza i użyć funkcja wyższego rzędu do kontroli, które odbywają się kod jako parametr. Takie podejście prawdopodobnie wymagać będzie nieco odświeżenia kodu. Oto, jak możesz go zaimplementować:

void helloWorld(){ 
    cout << "Hello World\n"; 
} 

void runSafe(void (*func)()){ 
    try { 
     func(); 
    } 
    catch (std::exception & e) 
    { 
     ErrorMsgLog::Log("Error"); 
     throw e; 
    } 
    catch (Exception & e) 
    { 
     ErrorMsgLog::Log("Error"); 
     throw e; 
    } 
    catch (...) 
    { 
     ErrorMsgLog::Log("Error"); 
     throw std::exception(); 
    } 
} 

int main(){ 
    runSafe(helloWorld); 
} 
+0

Ponieważ używasz C++, użyj 'std :: function' zamiast surowego wskaźnika funkcji. Użyj argumentów szablonu dla typu argumentu funkcji i typu zwracanego. –

Powiązane problemy