Si usted se encuentra en su código con una situación excepcional-es decir, si no tiene suficiente información en el contexto actual para decidir lo que hacer- puede enviar información acerca del error a un contexto mayor creando un objeto que contenga esa información y «lanzándolo» fuera de su contexto actual. Esto es lo que se llama lanzar una excepción. Este es el aspecto que tiene:
//: C01:MyError.cpp {RunByHand} class MyError { const char* const data; public: MyError(const char* const msg = 0) : data(msg) {} }; void f() { // Here we "throw" an exception object: throw MyError("something bad happened"); } int main() { // As you'll see shortly, we'll want a "try block" here: f(); } ///:~
Listado 2.2. C01/MyError.cpp
MyError es una clase normal, que en este caso acepta un char* como argumento del constructor. Usted puede usar cualquier tipo para lanzar (incluyendo los tipos predefinidos), pero normalmente creará clases especial para lanzar excepciones.
La palabra clave throw hace que suceda una serie de cosas relativamente mágicas. En primer lugar se crea una copia del objeto que se está lanzando y se «devuelve» desde la función que contiene la expresión throw, aun cuando ese tipo de objeto no es lo que normalmente la función está diseñada para devolver. Un modo simplificado de pensar acerca del tratamiento de excepciones es como un mecanismo alternativo de retorno (aunque llegará a tener problemas si lleva esta analogía demasiado lejos). También es posible salir de ámbitos normales lanzando una excepción. En cualquier caso se devuelve un valor y se sale de la función o ámbito.
Además es posible lanzar tantos tipos de objetos diferentes como se quiera. Típicamente, para cada categoría de error se lanzará un tipo diferente. La idea es almacenar la información en el objeto y en el nombre de la clase con el fin de quien esté en el contexto invocador pueda averiguar lo que hacer con esa excepción.