¿Cuál es una buena manera en C++ para detectar en un destructor que se está ejecutando durante el desenrollado de la pila debido a una excepción lanzada en oposición a una salida normal del alcance que desencadena el destructor? Me gustaría saber para poder crear una clase que tenga algún código de limpieza que siempre se ejecute en la salida normal pero se omita cuando ocurra una excepción.¿Detecta cuándo se ejecuta el destructor debido a una excepción?
Respuesta
std::uncaught_exception()
(definido en <exception>
) le informará por su destructor si se llamó debido a una excepción:
class A
{
public:
~A()
{
if (std::uncaught_exception()) {
// Called because of an exception
} else {
// No exception
}
}
};
¡Agradable, nunca supe que esto existía! :-) –
No es tan agradable como podría pensar - vea el artículo vinculado en mi publicación. – Simon
Esta es una manera que puedo pensar, pero parece torpe:
{
myCleanupClass unwindAction;
try {
// do some work which may throw exception.
} catch (...) {
unwindAction.disableDestructorWork();
throw;
}
}
No haga eso a menos que tenga una buena razón. El desenrollado de la pila es una función de lenguaje tal que todos los objetos automáticos dentro del bloque try
se aplicarán para desasignar, de modo que los recursos dentro de ellos tengan la oportunidad de liberarse.
Desea omitir la limpieza en dtor durante el desenrollado de la pila, lo que evita la intención original de la misma. Y correrá el riesgo de perder recursos.
Ejemplo
class CDBConnection
{
public:
CDBConnection()
{
m_db.open();
}
~CDBConnection()
{
if (!std::uncaught_exception())
m_db.close();
// if this is called during a stack unwinding,
// your DB connection will not be closed for sure.
// That's a resource leakage.
}
//..
private:
DB m_db;
};
void main()
{
//..
try
{
// code that may throw
CDBConnection db;
//..
}
catch(const CDBException& exp)
{
// properly handle the exception
}
}
Probablemente this artículo le ayudará. El artículo le mostrará los problemas con std :: uncaught_exception() y contiene un consejo sobre cómo lidiar con excepciones en destructores.
- 1. ¿Por qué mi destructor nunca se ejecuta?
- 2. ¿Cuándo se debe dejar que una aplicación se cuelgue debido a una excepción en Java (problema de diseño)?
- 3. excepción se detecta dos veces
- 4. Detecta aritmética de punteros debido a LARGEADDRESSAWARE
- 5. ¿Cuándo se llama un destructor de C++?
- 6. Excepción en destructor
- 7. Cuándo se llama a destructor en un servicio WCF
- 8. Destructor no llama cuando se produce una excepción
- 9. ¿Por qué no se solicita el destructor en la excepción?
- 10. spring jdbc ¿Cómo se detecta la excepción?
- 11. Cuándo volver a lanzar una excepción, cuándo devolver FALSO?
- 12. cuándo usar destructor en php?
- 13. ¿Cuándo debería crear un destructor?
- 14. ¿Cómo puedo saber si se lanzó una excepción SQL debido a una violación de clave externa?
- 15. ¿Cuándo y cómo se ejecuta Asynchronous Google Analytics?
- 16. ¿Saldrá() o una excepción evitará que se llame a un destructor de fin de ámbito?
- 17. Determine cuándo se ejecuta en una máquina virtual
- 18. MATLAB - ¿ejecuta el destructor de objetos cuando usa 'borrar'?
- 19. ¿Cuándo se ejecuta .Net en UNIX?
- 20. ¿Cuándo se ejecuta una consulta compilada que devuelve IQueryable?
- 21. Confundido sobre cuándo lanzar una excepción
- 22. AS3 - ¿Cuándo se ejecuta el recolector de basura?
- 23. Buscar si se produjo una excepción SQLException debido a un duplicado
- 24. MySQL Query ejecuta pero lanza una excepción
- 25. ¿Detecta cuándo se agrega una nueva propiedad a un objeto Javascript?
- 26. El hilo se ejecuta solo una vez
- 27. especificación de excepción de gcc destructor predeterminado
- 28. ¿Cuándo se ejecuta el recolector de basura .net?
- 29. Averiguar el origen de una excepción en C++ después de que se detecta?
- 30. ¿Amplify.store devuelve un error o detecta una excepción cuando se excede el límite de almacenamiento local?
¡Pregunta interesante! Estoy tentado de decir que no se puede hacer, porque los objetos realmente no saben que una excepción está activa, simplemente salen del alcance ya que la excepción desenrolla la pila, como si salieran de cualquier otra alcance. En todo caso, necesitaría algún "hackeo" específico de la plataforma ... –
¿Por qué quiere evitar la limpieza durante el desenrollado de la pila? –
@Eric Z: Pensé en usar esto para el registro automático de 'stack'. Algo similar a 'Log xxx (" funcA - ", arg1, arg2, arg3);', pero instrumentar las funciones es tedioso. –