c++ - son - try catch en c
¿Detectar cuándo se está ejecutando el destructor debido a que se ha lanzado una excepción? (4)
Aquí hay una forma en la que puedo pensar, pero parece torpe:
{
myCleanupClass unwindAction;
try {
// do some work which may throw exception.
} catch (...) {
unwindAction.disableDestructorWork();
throw;
}
}
¿Cuál es una buena manera en C ++ de detectar en un destructor que se está ejecutando durante el desenrollado de la pila debido a una excepción lanzada en lugar de una salida normal del alcance que activa 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 se produce una excepción.
Probablemente this artículo te ayude. El artículo te mostrará los problemas con std :: uncaught_exception () y contiene un consejo sobre cómo lidiar con las excepciones en los destructores.
std::uncaught_exception()
(definido en <exception>
) le dirá en su destructor si fue llamado debido a una excepción:
class A
{
public:
~A()
{
if (std::uncaught_exception()) {
// Called because of an exception
} else {
// No exception
}
}
};
No hagas eso a menos que tengas una buena razón . El desenrollado de la pila es una característica de lenguaje tal que todos los objetos automáticos dentro del bloque de 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ás 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
}
}