Tengo una API que internamente tiene algunas excepciones para el informe de errores. La estructura básica es que tiene un objeto de excepción raíz que hereda de std::exception
, luego arrojará alguna subclase de eso.forma correcta de almacenar una excepción en una variable
Dado que capturar una excepción arrojada en una biblioteca o hilo y atraparla en otra puede llevar a un comportamiento indefinido (al menos Qt se queja de ello y lo desautoriza en muchos contextos). Me gustaría envolver las llamadas de biblioteca en funciones que devolverán un código de estado y, si se produjo una excepción, una copia del objeto de excepción.
¿Cuál es la mejor manera de almacenar una excepción (con su comportamiento polimórfico) para su uso posterior? Creo que la futura API C++ 0x utiliza algo como esto. Entonces, ¿cuál es el mejor enfoque?
Lo mejor que puedo pensar es tener un método clone()
en cada clase de excepción que devolverá un puntero a una excepción del mismo tipo. Pero eso no es muy genérico y no trata las excepciones estándar en absoluto.
¿Alguna idea?
EDIT: Parece que C++ 0x tendrá a mechanism for this. Se describe como "magia de biblioteca". ¿Eso significa que no requiere ninguna de las funciones de lenguaje de C++ 0x? si no, ¿hay implementaciones que sean compatibles con C++ 03?
EDIT: Parece que boost tiene un implementation of exception copying. Mantendré la pregunta abierta para cualquier respuesta que no sea boost::copy_exception
.
EDITAR: Para responder a las preocupaciones de j_random_hacker sobre la causa de la excepción de un error de falta de memoria. Para esta biblioteca en particular y conjunto de excepciones, este no es el caso. Todas las excepciones derivadas del objeto de excepción raíz representan diferentes tipos de errores de análisis causados por una entrada de usuario no válida. Las excepciones relacionadas con la memoria simplemente provocarán el lanzamiento de un std::bad_alloc
, que se trata por separado.
Pero tenga en cuenta que la causa raíz de la excepción puede ser una condición de falta de memoria, en cuyo caso 'clone()' fallará si intenta llamar a 'new'. Esto se puede conseguir, por ejemplo al sobrecargar 'operator new()' para cada tipo de excepción para asignar desde un búfer estático, pero tampoco necesariamente es bonito. –
@j_random_hacker: Bueno, dado que nos estamos volviendo pedantes, lo que usted llama falta de memoria se conoce mejor como mal-alloc y no tiene que ser real de memoria. Otra razón para el mal-alloc es la solicitud de demasiada memoria, y en ese caso las siguientes pequeñas asignaciones tendrán éxito – sbk
@sbk: ¿Es realmente pedante considerar la posibilidad de quedarse sin memoria? –