Anuncios

Hola, a todos sean bienvenidos a mi nuevo post. Hoy trataremos sobre otra piedra fundamental en programacion, como detectar y resolver errores. Hasta ahora todos los codigos estan 100% libre de error, porque son de uso ilustrativo y todos fueron chequeados, para comenzar sobre el tema de hoy hablemos de los bugs, como se llaman habitualmente a los errores, y estos son algunos tipos de ellos:

  • Mala logica, es un error de tipo humano donde se realizo mal la logica y el programa se ejecuta correctamente pero no hace lo deseado
  • Sintactico, se utilizo el idioma, funcion o estructura incorrectos
Anuncios

Si bien el segundo problema puede ser detectado e informado por el compilador o el enlazador, en cambio el primer caso puede ser ocasionado por nosotros y no vamos a tener forma de notarlo hasta ejecutarlo, otro problema puede ser debido al usuario, este podria ingresar letras en un lugar donde espera numeros y esto va a generar un error con el programa, de incompatibilidad con el valor informado y salir del mismo, otro inconveniente es quedarnos sin recursos, por ejemplo la memoria o disco.
Para evitar esto trabajamos con excepciones para darle a nuestros programas la siguiente conducta ante un error:

  • Hacer que el programa falle
  • Informar al usuario y salir con elegancia
  • Informar al usuario y darle la posibilidad de volver a hacer la carga
  • Tomar una decision correctiva y continuar sin informar al usuario
Anuncios

Hablemos un poco sobre excepciones, estas son un tipo de objeto encargado de pasar desde el area del codigo con error a la area del codigo encargada de solucionarlo, se utilizan dos tipos de metodos, try() y catch(), su esructura es:

try {
    …Funciones….
}
catch(tipo de excepcion) {
    ….funciones…
}
Anuncios

Para ilustrar un poco mejor como es la estructura de los metodos para interceptar errores utilicemos el siguiente ejemplo:

error00.cpp

#include <iostream>

using namespace std;

const int TamanioPredet = 10;

class Arreglo
{
public:
 	Arreglo(int suTamanio = TamanioPredet);
 	Arreglo(const Arreglo & rhs);
 	~Arreglo() { delete [] apTipo; }
 	Arreglo & operator = (const Arreglo &);
 	int & operator[] (int desplazamiento);
 	const int & operator[] (int desplazamiento) const;
 	int ObtenersuTamanio() const { return suTamanio; }
 	friend ostream & operator << (ostream &, const Arreglo &);
 	class xLimite{};
private:
 	int *apTipo;
 	int suTamanio;
};

Arreglo::Arreglo (int tamanio):
 	suTamanio(tamanio)
 	{
 		apTipo = new int[ tamanio ];
		for(int i = 0; i < tamanio; i++)
 			apTipo[ i ] = 0;
 	}

Arreglo & Arreglo::operator=(const Arreglo & rhs)
{
 	if (this == &rhs)
 		return *this;
 	delete [] apTipo;
	suTamanio = rhs.ObtenersuTamanio();
 	apTipo = new int[ suTamanio ];
 	for( int i = 0; i < suTamanio; i++)
 		apTipo[ i ] = rhs[ i ];
 	return *this;
}

Arreglo::Arreglo(const Arreglo & rhs)
{
 	suTamanio = rhs.ObtenersuTamanio();
 	apTipo = new int[ suTamanio ];
	for(int i = 0; i < suTamanio; i++)
 		apTipo[ i ] = rhs[ i ];
}

int & Arreglo::operator[](int desplazamiento)
{
 	int tamanio = ObtenersuTamanio();
 	if (desplazamiento >= 0 && desplazamiento < ObtenersuTamanio())
 		return apTipo[ desplazamiento ];
 	throw xLimite();
 	return apTipo[ 0 ];
}

const int & Arreglo::operator[](int desplazamiento) const
{
 	int tamanio = ObtenersuTamanio();
 	if (desplazamiento >= 0 && desplazamiento < ObtenersuTamanio())
 		return apTipo[ desplazamiento ];
 	throw xLimite();
 	return apTipo[ 0 ];
}

ostream & operator<< (ostream & salida, const Arreglo & elArreglo)
{
 	for(int i = 0; i < elArreglo.ObtenersuTamanio(); i++)
 		salida << "[ " << i << " ]" << elArreglo[ i ] << endl;
 	return salida;
}

int main()
{
 	Arreglo arregloInt(20);
	try
 	{
 		for(int j = 0; j < 100; j++)
 		{
 			arregloInt[ j ] = j;
 			cout << "arregloInt[ " << j;
 			cout << " ] esta bien..." << endl;
 		}
 	}
 	catch (Arreglo::xLimite)
 	{
 		cout << "No se pudo procesar su entrada.\n";
 	}
	cout << "Listo!\n";
 	return 0;
}
Anuncios

En este codigo crearemos una clase llamada Arreglo, es como todas las clases creadas hasta ahora con una sola diferencia, incluimos a otra clase y esta se va a llamar xLimite, esto nos permitira que las dos clases esten relacionadas pero no tendran accesos entre si, es decir ni xLimite tendra acceso a los metodos de Arreglo ni Arreglo a los de xLimite (aunque no tiene ningun metodo declarado, recuerden que el compilador le asigna un constructor y destructor predeterminado). tambien en la definicion de los operadores de desplazamiento, vamos a utilizar una linea extra: throw xLimite(), la cual sera utilizada mas adelante siempre y cuando el valor de desplazamiento este fuera del rango y por ultimo lleva los parentesis para distinguir la llamada al constructor de xLimite y entre el uso de una constante enumerada. Veamos el main(), crearemos un objeto de tipo Arreglo llamado arregloInt con un tamaño de 20, luego creamos un bloque con try(), en el cual crearemos un ciclo for con el cual contaremos hasta 100 y comenzara a llenar el arregloInt y nos lo mostrara en pantalla, veamos la salida:

tinchicus@dbn001dsk:~/lenguaje/c++$ ./error00
arregloInt[ 0 ] esta bien…
arregloInt[ 1 ] esta bien…
arregloInt[ 2 ] esta bien…
arregloInt[ 3 ] esta bien…
arregloInt[ 4 ] esta bien…
arregloInt[ 5 ] esta bien…
arregloInt[ 6 ] esta bien…
arregloInt[ 7 ] esta bien…
arregloInt[ 8 ] esta bien…
arregloInt[ 9 ] esta bien…
arregloInt[ 10 ] esta bien…
arregloInt[ 11 ] esta bien…
arregloInt[ 12 ] esta bien…
arregloInt[ 13 ] esta bien…
arregloInt[ 14 ] esta bien…
arregloInt[ 15 ] esta bien…
arregloInt[ 16 ] esta bien…
arregloInt[ 17 ] esta bien…
arregloInt[ 18 ] esta bien…
arregloInt[ 19 ] esta bien…
No se pudo procesar su entrada.
Listo!
tinchicus@dbn001dsk:~/lenguaje/c++$
Anuncios

Pueden observar como fue incrementando a arregloInt pero al superar su tamaño, recuerden que establecimos un valor de 20, pasa al bloque de catch() y en este utilizamos a xLimite, esta hecha asi para asignarle un espacio de memoria, para en lugar de mostrarnos un mensaje de error nos devuelva un mensaje y salir del programa. Si eliminaran los bloques de try() y catch() al ejecutarlo obtendrian esto:

tinchicus@dbn001dsk:~/lenguaje/c++$ ./error00
arregloInt[ 0 ] esta bien…
arregloInt[ 1 ] esta bien…
arregloInt[ 2 ] esta bien…
arregloInt[ 3 ] esta bien…
arregloInt[ 4 ] esta bien…
arregloInt[ 5 ] esta bien…
arregloInt[ 6 ] esta bien…
arregloInt[ 7 ] esta bien…
arregloInt[ 8 ] esta bien…
arregloInt[ 9 ] esta bien…
arregloInt[ 10 ] esta bien…
arregloInt[ 11 ] esta bien…
arregloInt[ 12 ] esta bien…
arregloInt[ 13 ] esta bien…
arregloInt[ 14 ] esta bien…
arregloInt[ 15 ] esta bien…
arregloInt[ 16 ] esta bien…
arregloInt[ 17 ] esta bien…
arregloInt[ 18 ] esta bien… 
arregloInt[ 19 ] esta bien…
terminate called after throwing an instance of 'Arreglo::xLimite'
Abortado
tinchicus@dbn001dsk:~/lenguaje/c++$
Anuncios

Observen como salio con un error y termino el programa, para esto sirven los bloques try() y catch(), podran deducir cual es nuestro mayor inconveniente, donde ubicamos a nuestro bloque try(), para capturar un error de asignacion, un error del usuario o errores fuera de los limites, el funcionamiento es el siguiente: cuando se produce una excepcion se examina la pila de llamadas, y esta es el producto de cuando una parte del programa invoca a una funcion, try() luego rastrea la ruta de ejecucion y a medida que se va eliminando elementos de la pila se invocan los destructores pertinentes. Despues de cada bloque try() puede haber varios bloques catch(), se considera si existe una concordancia este va a ser manejado al ejecutar esa instruccion y en caso contrario seguira eliminando elementos de la pila. Como dijimos podemos utilizar mas de un bloque catch(), veamoslo a traves del siguiente ejemplo:

error01.cpp

#include <iostream>

using namespace std;

const int TamanioPredet = 10;

class Arreglo
{
public:
 	Arreglo(int suTamanio = TamanioPredet);
 	Arreglo(const Arreglo & rhs);
 	~Arreglo() { delete [] apTipo; }
 	Arreglo & operator = (const Arreglo &);
 	int & operator[] (int desplazamiento);
 	const int & operator[] (int desplazamiento) const;
 	int ObtenersuTamanio() const { return suTamanio; }
 	friend ostream & operator << (ostream &, const Arreglo &);
 	class xLimite{};
 	class xMuyGrande{};
 	class xMuyChico{};
 	class xCero{};
 	class xNegativo{};
private:
 	int *apTipo; 
	int suTamanio;
};

int & Arreglo::operator[](int desplazamiento)
{
 	int tamanio = ObtenersuTamanio();
 	if (desplazamiento >= 0 && desplazamiento < ObtenersuTamanio())
 		return apTipo[ desplazamiento ];
 	throw xLimite(); 
	return apTipo[ 0 ];
}

const int & Arreglo::operator[](int desplazamiento) const
{
 	int tamanio = ObtenersuTamanio();
 	if (desplazamiento >= 0 && desplazamiento < ObtenersuTamanio())
 		return apTipo[ desplazamiento ];
 	throw xLimite();
 	return apTipo[ 0 ];
}

Arreglo::Arreglo (int tamanio):
 	suTamanio(tamanio)
 	{
 	if (tamanio == 0) throw xCero();
 	if (tamanio < 10) throw xMuyChico(); 
	if (tamanio > 30000) throw xMuyGrande();
 	if (tamanio < 0) throw xNegativo();
	apTipo = new int[ tamanio ];
	for(int i = 0; i < tamanio; i++)
 		apTipo[ i ] = 0;
}

int main()
{
	try
	{
		int numero = 0;
		cout << "Ingrese un numero: ";
		cin >> numero;
 		Arreglo arregloInt(numero);
		for(int j = 0; j < 100; j++)
 		{
 			arregloInt[ j ] = j;
 			cout << "arregloInt[ " << j;
 			cout << " ] esta bien..." << endl;
 		}
	}
	catch (Arreglo::xLimite)
	{
 		cout << "No se pudo procesar su entrada.\n";
	}
	catch(Arreglo::xMuyGrande)
	{
 		cout << "Este arreglo es muy grnde...\n";
	}
	catch(Arreglo::xMuyChico)
	{
 		cout << "Este arreglo es muy chico...\n";
	}
	catch(Arreglo::xCero)
	{
 		cout << "Pidio un arreglo de cero objetos\n";
	}
	catch(...)
	{
 		cout << "Algo salio mal!\n";
	}
	cout << "Listo!\n";
	return 0;
}
Anuncios

En este caso vamos a hacer una serie de modificaciones con respecto al ejemplo anterior, en el primer caso, agregaremos la posibilidad de ingresar un valor y el otro va a ser la cantidad de bloques catch que agregaremos, para ello tambien agregamos unas clases dentro de la clase Arreglo:

class Arreglo
{
public:
     Arreglo(int suTamanio = TamanioPredet);
     Arreglo(const Arreglo & rhs);
     ~Arreglo() { delete [] apTipo; }
     Arreglo & operator = (const Arreglo &);
     int & operator[] (int desplazamiento);
     const int & operator[] (int desplazamiento) const;
     int ObtenersuTamanio() const { return suTamanio; }
     friend ostream & operator << (ostream &, const Arreglo &);
     class xLimite{};
     class xMuyGrande{};
     class xMuyChico{};
     class xCero{};
     class xNegativo{};
private:
     int *apTipo; 
     int suTamanio;
};
Anuncios

Las cuales nos serviran para identificar a cada uno de nuestros catchs, pero como los activaremos, esto lo haremos atraves del siguiente constructor:

Arreglo::Arreglo (int tamanio):
 	suTamanio(tamanio)
 	{
 	if (tamanio == 0) throw xCero();
 	if (tamanio < 10) throw xMuyChico(); 
	if (tamanio > 30000) throw xMuyGrande();
 	if (tamanio < 0) throw xNegativo();
	apTipo = new int[ tamanio ];
	for(int i = 0; i < tamanio; i++)
 		apTipo[ i ] = 0;
}
Anuncios

Observen como dependiendo de la condicion del Arreglo creado ira a un bloque catch() u otro, esto gracias a la funcion throw, como en este caso en el main() vamos a crear el objeto de tipo Arreglo llamado arregloInt() con el valor ingresado por medio de numero pero a diferencia del codigo anterior ahora si ira dentro del try(), luego tendremos distintos bloques donde devolveremos un mensaje en base al error ocurrido, veamos algunas salidas de este programa:

tinchicus@dbn001dsk:~/lenguaje/c++$ ./error01
Ingrese un numero: 0
Pidio un arreglo de cero objetos
Listo!
tinchicus@dbn001dsk:~/lenguaje/c++$ ./error01
Ingrese un numero: 10
arregloInt[ 0 ] esta bien…
arregloInt[ 1 ] esta bien…
arregloInt[ 2 ] esta bien…
arregloInt[ 3 ] esta bien…
arregloInt[ 4 ] esta bien…
arregloInt[ 5 ] esta bien…
arregloInt[ 6 ] esta bien…
arregloInt[ 7 ] esta bien…
arregloInt[ 8 ] esta bien…
arregloInt[ 9 ] esta bien…
No se pudo procesar su entrada.
Listo!
tinchicus@dbn001dsk:~/lenguaje/c++$ ./error01
Ingrese un numero: 100000
Este arreglo es muy grnde…
Listo!
tinchicus@dbn001dsk:~/lenguaje/c++$ ./error01
Ingrese un numero: 5
Este arreglo es muy chico…
Listo!
tinchicus@dbn001dsk:~/lenguaje/c++$
tinchicus@dbn001dsk:~/lenguaje/c++$ ./error01
Ingrese un numero: 100
arregloInt[ 0 ] esta bien…
arregloInt[ 1 ] esta bien…
arregloInt[ 2 ] esta bien…
arregloInt[ 3 ] esta bien…
arregloInt[ 4 ] esta bien…
arregloInt[ 5 ] esta bien…
arregloInt[ 6 ] esta bien…
arregloInt[ 7 ] esta bien…
arregloInt[ 8 ] esta bien…
arregloInt[ 9 ] esta bien…
arregloInt[ 10 ] esta bien…
arregloInt[ 11 ] esta bien…
arregloInt[ 12 ] esta bien…
arregloInt[ 13 ] esta bien…
arregloInt[ 14 ] esta bien…
arregloInt[ 15 ] esta bien…
arregloInt[ 16 ] esta bien…
arregloInt[ 17 ] esta bien…
arregloInt[ 18 ] esta bien…
arregloInt[ 19 ] esta bien…
arregloInt[ 20 ] esta bien…
arregloInt[ 21 ] esta bien…
arregloInt[ 22 ] esta bien…
arregloInt[ 23 ] esta bien…
arregloInt[ 24 ] esta bien…
arregloInt[ 25 ] esta bien…
arregloInt[ 26 ] esta bien…
arregloInt[ 27 ] esta bien…
arregloInt[ 28 ] esta bien…
arregloInt[ 29 ] esta bien…
arregloInt[ 30 ] esta bien…
arregloInt[ 31 ] esta bien…
arregloInt[ 32 ] esta bien…
arregloInt[ 33 ] esta bien…
arregloInt[ 34 ] esta bien…
arregloInt[ 35 ] esta bien…
arregloInt[ 36 ] esta bien…
arregloInt[ 37 ] esta bien…
arregloInt[ 38 ] esta bien…
arregloInt[ 39 ] esta bien…
arregloInt[ 40 ] esta bien…
arregloInt[ 41 ] esta bien…
arregloInt[ 42 ] esta bien…
arregloInt[ 43 ] esta bien…
arregloInt[ 44 ] esta bien…
arregloInt[ 45 ] esta bien…
arregloInt[ 46 ] esta bien…
arregloInt[ 47 ] esta bien…
arregloInt[ 48 ] esta bien…
arregloInt[ 49 ] esta bien…
arregloInt[ 50 ] esta bien…
arregloInt[ 51 ] esta bien…
arregloInt[ 52 ] esta bien…
arregloInt[ 53 ] esta bien…
arregloInt[ 54 ] esta bien…
arregloInt[ 55 ] esta bien…
arregloInt[ 56 ] esta bien…
arregloInt[ 57 ] esta bien…
arregloInt[ 58 ] esta bien…
arregloInt[ 59 ] esta bien…
arregloInt[ 60 ] esta bien…
arregloInt[ 61 ] esta bien…
arregloInt[ 62 ] esta bien…
arregloInt[ 63 ] esta bien…
arregloInt[ 64 ] esta bien…
arregloInt[ 65 ] esta bien…
arregloInt[ 66 ] esta bien…
arregloInt[ 67 ] esta bien…
arregloInt[ 68 ] esta bien…
arregloInt[ 69 ] esta bien…
arregloInt[ 70 ] esta bien…
arregloInt[ 71 ] esta bien…
arregloInt[ 72 ] esta bien…
arregloInt[ 73 ] esta bien…
arregloInt[ 74 ] esta bien…
arregloInt[ 75 ] esta bien…
arregloInt[ 76 ] esta bien…
arregloInt[ 77 ] esta bien…
arregloInt[ 78 ] esta bien…
arregloInt[ 79 ] esta bien…
arregloInt[ 80 ] esta bien…
arregloInt[ 81 ] esta bien…
arregloInt[ 82 ] esta bien…
arregloInt[ 83 ] esta bien…
arregloInt[ 84 ] esta bien…
arregloInt[ 85 ] esta bien…
arregloInt[ 86 ] esta bien…
arregloInt[ 87 ] esta bien…
arregloInt[ 88 ] esta bien…
arregloInt[ 89 ] esta bien…
arregloInt[ 90 ] esta bien…
arregloInt[ 91 ] esta bien…
arregloInt[ 92 ] esta bien…
arregloInt[ 93 ] esta bien…
arregloInt[ 94 ] esta bien…
arregloInt[ 95 ] esta bien…
arregloInt[ 96 ] esta bien…
arregloInt[ 97 ] esta bien…
arregloInt[ 98 ] esta bien…
arregloInt[ 99 ] esta bien…
Listo!
tinchicus@dbn001dsk:~/lenguaje/c++$
Anuncios

En este caso podemos ver varios tipos de salida, la primera cuando se llama a xCero, es decir informamos un numero de valor cero, con un valor de 10 donde como no puede continuar creando elementos nos devuelve un error porque no puede continuar con el bucle for (se llamo a xLimite), cuando ingresamos un valor de 100000 se llamo a xMuyGrande, despues se llamo a xMuyChico porque el valor era menor a 10, por ultimo vemos que se ejecuto correctamente con el valor de 100. nuestro ultimo catch(…) significa «atrapar todo» o lo mismo que decir el catch() predeterminado. El cual ante un error no identificado en los bloques anteriores nos mostrara ese mensaje de error, ahora si hablemos sobre el ultimo tema: jerarquia de excepciones.

Anuncios

Como vimos las excepciones son basicamente clases y podemos crear una clase de la cual se van a derivar las otras, veamoslo a traves del siguiente ejemplo:

error02.cpp

#include <iostream>

using namespace std;

const int TamanioPredet = 10;

class Arreglo
{
public:
 	Arreglo(int suTamanio = TamanioPredet);
 	Arreglo(const Arreglo & rhs);
 	~Arreglo() { delete [] apTipo; }
 	Arreglo & operator = (const Arreglo &);
 	int & operator[] (int desplazamiento);
 	const int & operator[] (int desplazamiento) const;
 	int ObtenersuTamanio() const { return suTamanio; }
 	friend ostream & operator << (ostream &, const Arreglo &);
 	class xLimite{};
 	class xTamanio{};
 	class xMuyGrande : public xTamanio{};
 	class xMuyChico: public xTamanio{};
 	class xCero: public xMuyChico{};
 	class xNegativo: public xTamanio{};
private:
 	int *apTipo;
 	int suTamanio;
};

int & Arreglo::operator[](int desplazamiento)
{
 	int tamanio = ObtenersuTamanio();
 	if (desplazamiento >= 0 && desplazamiento < ObtenersuTamanio())
 		return apTipo[ desplazamiento ];
 	throw xLimite();
 	return apTipo[ 0 ];
}
const int & Arreglo::operator[](int desplazamiento) const
{
 	int tamanio = ObtenersuTamanio();
 	if (desplazamiento >= 0 && desplazamiento < ObtenersuTamanio())
 		return apTipo[ desplazamiento ];
 	throw xLimite();
 	return apTipo[ 0 ];
}

Arreglo::Arreglo (int tamanio):
 	suTamanio(tamanio)
 	{
 	if (tamanio == 0)
 		throw xCero();
 	if (tamanio < 0) throw xNegativo(); 
	if (tamanio > 30000) throw xMuyGrande();
 	if (tamanio < 10) throw xMuyChico();
	apTipo = new int[ tamanio ];
	for(int i = 0; i < tamanio; i++)
 		apTipo[ i ] = 0;
	}

int main()
{
	try
 	{
 		Arreglo arregloInt(0);
		for(int j = 0; j < 100; j++)
 		{
 			arregloInt[ j ] = j;
 			cout << "arregloInt[ " << j;
 			cout << " ] esta bien..." << endl;
 		}
 	}
 	catch (Arreglo::xLimite)
 	{
 		cout << "No se pudo procesar su entrada.\n";
 	}
 	catch(Arreglo::xMuyGrande)
 	{
 		cout << "Este arreglo es muy grnde...\n";
 	}
 	catch(Arreglo::xMuyChico)
 	{
 		cout << "Este arreglo es muy chico...\n";
 	}
 	catch(Arreglo::xCero)
 	{
 		cout << "Pidio un arreglo de cero objetos\n";
 	}
 	catch(...)
 	{
 		cout << "Algo salio mal!\n";
 	}
	cout << "Listo!\n";
 	return 0;
}
Anuncios

En este ejemplo agregamos a la clase Arreglo una nueva clase llamada xTamanio, y vamos a modificar las derivaciones de nuestras cuatro clases, ahora haremos a xMuyGrande, xMuyChico y a xNegativo herederos de xTamanio y a xCero lo hacemos heredero de xMuyChico. Cuando lo compilemos nos dara el siguiente error:

tinchicus@dbn001dsk:~/lenguaje/c++$ g++ error02.cpp -o error02
error02.cpp: In function ‘int main()’:
error02.cpp:83:3: warning: exception of type ‘Arreglo::xCero’ will be caught
   catch(Arreglo::xCero)
   ^~~~~
error02.cpp:79:3: warning:    by earlier handler for ‘Arreglo::xMuyChico’
   catch(Arreglo::xMuyChico)
   ^~~~~
tinchicus@dbn001dsk:~/lenguaje/c++$
Anuncios

Esto es debido a que al compilarlo observa como xCero sera ocultado por otro manipulador, en este caso xMuyChico, esto es porque al ser xCero heredero de xMuyChico el va a tener la prioridad, y como solucionamos esto? De la siguiente forma, primero veamos el bloque con el conflicto:

 	catch (Arreglo::xLimite)
 	{
 		cout << "No se pudo procesar su entrada.\n";
 	}
 	catch(Arreglo::xMuyGrande)
 	{
 		cout << "Este arreglo es muy grnde...\n";
 	}
 	catch(Arreglo::xMuyChico) // Aca esta un problema
 	{
 		cout << "Este arreglo es muy chico...\n";
 	}
 	catch(Arreglo::xCero) // y aca esta el otro
 	{
 		cout << "Pidio un arreglo de cero objetos\n";
 	}
 	catch(...)
 	{
 		cout << "Algo salio mal!\n";
 	}
Anuncios

Como ven primero llama a xMuyChico y por ende el compilador se da cuenta que este catch() va a ocultar a xCero, para solucionarlo debemos hacer esto:

 	catch (Arreglo::xLimite)
 	{
 		cout << "No se pudo procesar su entrada.\n";
 	}
 	catch(Arreglo::xMuyGrande)
 	{
 		cout << "Este arreglo es muy grnde...\n";
 	}
 	catch(Arreglo::xCero)
 	{
 		cout << "Pidio un arreglo de cero objetos\n";
 	}
 	catch(Arreglo::xMuyChico)
 	{
 		cout << "Este arreglo es muy chico...\n";
 	}
 	catch(...)
 	{
 		cout << "Algo salio mal!\n";
 	}
Anuncios

Con este simple cambio, no importa si xCero es heredero de xMuyChico porque al ver el orden de los catch(), este sabra darle la prioridad a xCero por sobre xMuyChico, entonces al compilarlo no nos dara ningun error y nos mostrara esta salida:

tinchicus@dbn001dsk:~/lenguaje/c++$ ./error02
Pidio un arreglo de cero objetos
Listo!
tinchicus@dbn001dsk:~/lenguaje/c++$
Anuncios

Hasta aqui hemos dado nuestros primeros pasos en como interceptar errores, hemos visto los dos tipos de errores mas tipicos, los metodos try() y catch() para interceptarlos, algunas opciones de como mostrarlos a los usuarios y por ultimo que ellos tambien tienen una jerarquia y como solucionarlo, en nuestro proximo post ahondaremos un poco mas en como interceptar los errores y vincularlos con otras lecciones. Espero les haya sido util, sigueme en tumblr, Twitter o Facebook para recibir una notificacion cada vez que subo un nuevo post en este blog, nos vemos en el proximo post.

Anuncios

Tengo un Patreon donde podes acceder de manera exclusiva a material para este blog antes de ser publicado, sigue los pasos del link para saber como.

Tambien podes donar

Es para mantenimiento del sitio, gracias!

$1.50

Anuncio publicitario