Excepciones

Capturando excepciones Las excepciones son un mecanismo de c++ para capturar errores que se producen en tiempo de ejecucion. Un programa puede estar bien hecho pero por causas exogenas pueden producirse errores. Mediante este sistema hacemos que el codigo sea mucho mas ROBUSTO.

/**
* Excepciones.cpp
* codigo que muestra como capturar excepciones y evitar 
que el programa
* finalice inesperadamente.
*
* Pello Xabier Altadill Izura
*
*/

using namespace std;
#include <iostream>
#include <fstream>
#include <stdexcept> 

// programa principal, para las pruebas
int main () {

	int i;
	float flotante;
	char *palabra;
	char buffer[5];

	ifstream ficheroInexistente;

	// para capturar excepciones debemos crear un bloque try-catch
	// que englobe algun momento problematico o critico del programa:
	// try { codigo; } catch(TipoDeError) { codigo_corrector; }

	// lo habitual suele ser alguna situacion que dependa de la existencia
	// o no de un fichero, la entrada de datos de un usuario, etc..
	// El programa no puede controlar lo que le meten, pero puede estar
	// preparado para el error, reconducir la ejecucion y corregir la situacion

	try 
	{ // inicio del bloque. Preparamos una serie de putadas...
		
		cout << "Mete lo primero que se te ocurra, distinto de float: " << endl;
		cin >> flotante;

		char * buff = new char[100000000];
		ficheroInexistente.open("MotorDeAgua.txt");
		
		ficheroInexistente.getline(buffer,255);
		ficheroInexistente.close();
	}
	catch(std::bad_alloc& error_memoria)
	{
	
		cout << "Error de asignacion" << error_memoria.what() << endl; 
		
	} // podemos seguir capturando
	catch (std::exception& stdexc) 
	{ // este es el tipo de error que se espera
	  // y entre llaves metemos el codigo que se ejecuta en caso de error.
	
		cout << "Error general, mensaje: " << stdexc.what() << endl;
	}


	return 1;

}

Excepciones personalizadas Una clase puede definir sus propias excepciones. Un mecanismo muy util para malos usos de los objetos. Definimos la clase coche y preparamos el codigo para capturar posibles fallos debidos a la falta de combustible.

/**
* Coche.hpp
* Definicion de la clase coche, en la que se muestra el 
uso de excepciones
*
* Pello Xabier Altadill Izura 
* 
*/

#include<iostream>

class Coche {

public:

	Coche();
	
	Coche(char *m,int cil,int cab, int litros);
	
	~Coche();
	
	void arranca();
	
	void echaCombustible();
	
	void detiene();

	void acelera();


private:
	
	char *marca;
	
	int cilindrada;

	int caballos; 
	
	int litrosCombustible;

};

// clase exclusiva para excepciones.
// Nota: la podemos definir DENTRO de la Clase coche, como un atributo MAS
class Averia {

public:
	
	// constructor
	Averia():mensaje("Error") {}
	
	// constructor con mensaje
	Averia(char *mensaje) {
	
		this->mensaje = mensaje;

	}


	char* dimeQuePasa() { return this->mensaje; };


private:
	
	char *mensaje;

};

Y la implementacion

/**
* Coche.cpp
* Implementacion de la clase coche, en la que se 
muestra el uso de excepciones
*
* Pello Xabier Altadill Izura 
* Compilacion: g++ -o Coche Coche.cpp
*/

#include "Coche.hpp"

Coche::Coche() {
	
	cout << "Coche creado." << endl;

}


Coche::Coche (char *m,int cil,int cab, int litros) {
	
	marca = m;
	cilindrada = cil;
	caballos = cab;
	litrosCombustible = litros;

	cout << "Coche creado." << endl;

}


Coche::~Coche() {
	
	cout << "Coche destruido." << endl;

}


// el coche arranca
void Coche::arranca() {
	
	// si no hay combustible: EXCEPCION!
	if (litrosCombustible == 0) {

		throw Averia(); 

	}

	litrosCombustible--;
	cout << "Arrancando: brummm! " << endl;

}


// el coche se detien
void Coche::detiene() {

	cout << "Deteniendo coche " << endl;

}


// el coche acelera
void Coche::acelera() {
	
	if (litrosCombustible == 0) {
		throw Averia("No puedo acelerar sin combustible"); 
	}
	
	cout << "Acelerando: BRRRRRUMMMMmmmmmmmmh!! " << endl;
}


// funcion principal para pruebas
int main () {

	int i;
	
	Coche buga("Seat",250,1300,0);
	Coche tequi("Audi",260,1500,1);

	// vamos a arrancar el coche pero si algo falla
	// capturamos la excepcion

	try {

		buga.arranca();
	
	} catch (Averia excepcion) {
	
		cout << "Excepcion. Jar que no puedo. " << endl;

	}

	// arracamos el tequi
	tequi.arranca();

	// provocamos la excepcion y la capturamos mostrando la explicacion.
	
	try {
	
		buga.acelera();

	} catch (Averia excepcion) {
		
		cout << "Jar que no puedo. " << excepcion.dimeQuePasa() << endl;

	}

	
	return 0;

}

Figura: el control de excepciones nos proporciona mas robustez.