2014-10-17 2 views
6

Я пытаюсь отладить мое приложение, используя исключения catch-rethrows. Мой код обработки исключений длиннее, чем некоторые из блоков, которые я отлаживаю, и все они скопированы.Как сделать код исключения DRY?

Есть ли лучший способ повторного выражения приведенного ниже кода? Я подозреваю, что макросы - это путь сюда, но я обычно избегаю макросов, таких как чума.

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

'forward' все исключения для шаблона функции? – user2485710

+4

Создайте 'Exception' подтип' std :: exception', как и любой обычный тип исключения. – rightfold

+0

1. Это не C++ 11. Не удается переслать. 2. Исключение - это класс Borland C++ Builder. Кроме того, даже если я * только * обрабатывал std :: exception, я все равно хотел бы уйти от копирования. – QuestionC

ответ

0

Лучший способ реализовать это, вероятно, с использованием макросов. Определение макроса немного уродливое, но вызов макроса будет довольно простым, и вам не нужно будет повторно организовывать код. Вот пример, который показывает, как можно реализовать:

#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"; 
) 
} 

Если вы действительно непреклонны не с помощью макросов, можно использовать подход, предложенный @juanchopanza и использовать функцию высшего порядка для проверки, который принимает код в качестве параметра. Этот подход, вероятно, потребует, чтобы вы немного реорганизовали свой код. Вот как вы могли бы это реализовать:

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

Поскольку вы используете C++, используйте «std :: function» вместо необработанного указателя функции. Используйте аргументы шаблона для типа аргумента функции и типа возвращаемого значения. –

Смежные вопросы