Dado que no hay finally
en C++ you have to use the RAII patrón de diseño en su lugar, si desea que su código sea excepcionalmente seguro. Una forma de hacer esto es mediante el uso del destructor de una clase local de esta manera:Reemplazo correcto de la falta 'finalmente' en C++
void foo() {
struct Finally {
~Finally() { /* cleanup code */ }
} finalizer();
// ...code that might throw an exception...
}
Esta es una gran ventaja sobre la solución recta hacia adelante, ya que no tiene que escribir el código de limpieza 2 veces:
try {
// ...code that might throw an exception...
// cleanup code (no exception)
} catch (...) {
// cleanup code (exception)
throw;
}
Una gran desventaja de la solución de clase local es que no puede acceder directamente a las variables locales en su código de limpieza. Por lo que se hinchan su código mucho si es necesario tener acceso a ellos sin tener en cuenta:
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...
}
}
Así que mi pregunta es: ¿Hay una solución que combina ambas ventajas? Para que a) a no tenga que escribir código duplicado yb) pueda acceder a las variables locales en el código de limpieza, como task
en el último ejemplo, pero sin dicho código inflado.
Eso es feo. ¡Deberías crear un RunObject o algo así! –
+1 por preguntar esto porque es muy común ver a personas que no están familiarizadas con 'RAII' pensando que' finalmente' es bueno ... –
"no tiene que escribir el código de limpieza 2 veces". ¿Por qué escribirías código dos veces, por alguna razón? Para eso están las subrutinas = P Neutral en la pregunta de RAII vs finalmente, pero escribir código dos veces es una pista falsa: podría crear una rutina de limpieza, pasarle tareas y llamarla en dos lugares. No se necesita duplicación de código. En su ejemplo simple, eso lógicamente es parte del destructor de la tarea. Pero si hay alguna razón por la que desea la limpieza en foo, entonces cree una rutina de limpieza local allí. – ToolmakerSteve