Поскольку в С++ нет finally
вам нужно использовать шаблон дизайна RAII, если вы хотите, чтобы ваш код был безопасным для исключений, Один из способов сделать это - использовать деструктор локального класса следующим образом:
void foo() {
struct Finally {
~Finally() { /* cleanup code */ }
} finalizer();
// ...code that might throw an exception...
}
Это большое преимущество перед прямым решением, потому что вам не нужно писать код очистки 2 раза:
try {
// ...code that might throw an exception...
// cleanup code (no exception)
} catch (...) {
// cleanup code (exception)
throw;
}
Большим недостатком решения локального класса является то, что вы не можете напрямую обращаться к локальным переменным в вашем коде очистки. Таким образом, он сильно раздует ваш код, если вам нужен доступ к ним независимо:
void foo() {
Task* task;
while (task = nextTask()) {
task->status = running;
struct Finally {
Task* task;
Finally(Task* task) : task(task) {}
~Finally() { task->status = idle; }
} finalizer(task);
// ...code that might throw an exception...
}
}
Итак, мой вопрос: Есть ли решение, которое сочетает в себе оба преимущества? Так что вам a) не нужно писать повторяющийся код и b) может обращаться к локальным переменным в коде очистки, например, task
в последнем примере, но без такого раздувания кода.