PDF de programación - SEMINARIO DE C++ (orientado a programadores java, pero no es parte del plan piloto, sólo para alumnos de AED) Sesión 3

Imágen de pdf SEMINARIO DE C++ (orientado a programadores java, pero no es parte del plan piloto, sólo para alumnos de AED) Sesión 3

SEMINARIO DE C++ (orientado a programadores java, pero no es parte del plan piloto, sólo para alumnos de AED) Sesión 3gráfica de visualizaciones

Actualizado el 20 de Mayo del 2018 (Publicado el 18 de Enero del 2017)
897 visualizaciones desde el 18 de Enero del 2017
233,6 KB
12 paginas
Creado hace 15a (06/10/2008)
Algoritmos y Estructuras de Datos

2º de Ingeniería Informática, Curso 2008/2009

SEMINARIO DE C++
(orientado a programadores java,

pero no es parte del plan piloto, sólo para alumnos de AED)



Sesión 3



Contenidos:

1. Funciones y clases genéricas
2. Excepciones
3. Asertos
4. El puntero this
5. Redefinición de operadores
Ejemplo



Algoritmos y Estructuras de Datos, 2007/2008
Seminario de C++ – Sesión 3

2/12

1. Funciones y clases genéricas1



• Genericidad (parametrización de tipo): el significado de una función o de un
tipos de datos está definido en base a unos parámetros de tipo que pueden variar.
o Ejemplo: funciones genéricas. En lugar de: OrdenaInt(int array[]),
OrdenaCharP(char *array[]), OrdenaFloat(float array[]), ...,
tenemos Ordena<T>(T array[]).
o Ejemplo: clases genéricas. En lugar de las clases PilaInt, PilaChar,

PilaFloat, ..., tenemos una clase genérica Pila<T>.

• En C++, las funciones y clases genéricas se definen mediante sentencias

template (plantilla). La sintaxis es:

template < parámetros genéricos > función o clase genérica


- parámetros genéricos: Lista con uno o varios tipos genéricos (clases). Por

ejemplo: template <class T>..., template <class A, class B>...

- función o clase genérica: Declaración normal de una función o una clase,

pudiendo usar los tipos de la lista de parámetros genéricos.





• Funciones genéricas ---------------------------------------------------------------------

o Definición.
template < parámetros genéricos >
tipoDevuelto nombreFunción ( parámetros de la función )
{
cuerpo de la función
}

o Utilización. Llamar directamente a la función. El compilador, según los tipos

de los parámetros de entrada, instanciará la versión adecuada.

• Ejemplo. Función genérica ordena(T array[], int tam), que ordena un

array de elementos de cualquier tipo T.
#include <string> // Contiene la clase string, alternativa
// a los (char *) de C
#include <iostream>
using namespace std;

template <class T>
void ordena (T array[], int tam)
{
for (int i= 0; i<tam-1; i++)
for (int j= i+1; j<tam; j++)
if (array[j]<array[i]) {
T tmp= array[i];
array[i]= array[j];
array[j]= tmp;
}
}


1 desde la versión 1.5 (octubre 2004) java incluye clases genéricas; ¿visto en primero?

Algoritmos y Estructuras de Datos, 2007/2008
Seminario de C++ – Sesión 3


3/12

template <class T>
void escribe (T array[], int tam)
{
for (int i= 0; i<tam; i++)
cout << array[i] << (i<tam-1? ", ": "\n");
}
#define numElems(ARRAY) sizeof(ARRAY)/sizeof(*ARRAY)
main ()
{
int a1[]= {65, 23, 12, 87};
ordena (a1, numElems(a1));
escribe(a1, numElems(a1));

string a2[]= {"hola", "esto", "es", "una", "prueba"};
ordena (a2, numElems(a2));
escribe(a2, numElems(a2));
}


• Clases genéricas --------------------------------------------------------------------------



o Definición de la clase.

template < parámetros genéricos >
class nombreClase
{
definición de miembros de la clase
};





o Implementación de los métodos. Para cada método de la clase tenemos:

template < parámetros genéricos >
tipoDevuelto nombreclase<par>::nombreFunción ( parámetros )
{
cuerpo de la función
}

o Utilización. La clase genérica se debe instanciar a un tipo concreto antes de

usarla. Instanciación: nombreclase<parámetros>.

• Ejemplo. Clase genérica pila<T>, de las pilas de cualquier tipo T.


#include <iostream>
#define MAXIMO 100
using namespace std;

template <class T> // Declaración de la clase
class pila
{
private:
int ultimo;
T datos[MAXIMO];
public:
pila () {ultimo= 0;} // Constructor
void push (T v);
void pop ();
T tope();
};

Algoritmos y Estructuras de Datos, 2007/2008
Seminario de C++ – Sesión 3

4/12


// Implementación de los métodos
template <class T>
void pila<T>::push (T v)
{
if (ultimo<MAXIMO)
datos[ultimo++]= v;
}

template <class T>
void pila<T>::pop ()
{
if (ultimo>0)
ultimo--;
}

template <class T>
T pila<T>::tope ()
{
return datos[ultimo-1];
}



// Programa principal
// Ejemplo de uso de la clase genérica
main ()
{
pila<int> p1; // p1 es una pila de enteros
p1.push(4); p1.push(9);
p1.pop();
cout << p1.tope() << '\n';

pila<char *> p2; // p2 es una pila de cadenas
p2.push("Ultimo"); p2.push("en"); p2.push("entrar");
p2.push("primero"); p2.push("en"); p2.push("salir");
for (int i= 0; i<6; i++, p2.pop())
cout << p2.tope() << '\n';

pila<float> *p3; // p3 es una pila de float que
p3= new pila<float>; // se crea dinámicamente
p3->push(1.3); p3->push(2.19); p3->push(3.14);
cout << p3->tope() << '\n';
delete p3;
}



• Probar:

1. Probar pilas de otros tipos: pila<char>, pila<pila<char> >, etc.
2. Implementar una operación igual, que compare dos pilas y devuelva true si

son iguales.

3. Probar la función igual.



• Existe una "pequeña pega" relacionada con las clases genéricas y la compilación

separada: el compilador sólo genera código cuando se instancia la clase genérica.

Problema: si separamos la definición de una clase genérica en fichero de
cabecera (pila.hpp) y de implementación (pila.cpp), la compilación (g++ -c
pila.cpp) no genera código objeto. Si otro módulo usa la case genérica (#include
"pila.hpp"), el compilador dirá que no encuentra la implementación de la clase.
la definición como
implementación de la clase deben ir en el mismo fichero, el hpp.

las clases genéricas,

Solución: para

tanto

la

Algoritmos y Estructuras de Datos, 2007/2008
Seminario de C++ – Sesión 3


2. Excepciones2

5/12



• ¿Qué hacer si se produce un error irreversible dentro de un procedimiento? Por
ejemplo, hacer una división por cero, aplicar tope() sobre una pila vacía,
imposibilidad de reservar más memoria o de leer un fichero, etc.
1. Mostrar un mensaje de error por pantalla, o por la salida de error estándar:

cerr << "Error: la pila está vacía";

2. Devolver al procedimiento que hizo la llamada un valor especial que

signifique "se ha producido un error".

3. Interrumpir la ejecución del programa: exit(1)
4. No hacer nada y continuar con la ejecución del programa como mejor se

pueda.

5. Provocar o lanzar una excepción.

• Significado de las excepciones:

ejecución en ese punto.

para manejar excepciones.

1. El procedimiento que lanza la excepción (lo llamamos A), interrumpe su

2. El procedimiento que ha llamado al A (lo llamamos B), debe tener un código

3. Si el procedimiento B no maneja la excepción, la excepción pasa al que ha
llamado al B, y así sucesivamente hasta que alguien trate la excepción
(propagación de la excepción).

4. Si la excepción se propaga hasta el main() y este no maneja la excepción,

se interrumpe la ejecución del programa y se muestra un mensaje de error.



• Conceptualmente, una excepción es un objeto3.
class ErrorPilaVacia {};
class DivisionPorCero {};
• Provocar una excepción. Sentencia: throw 4 nombreClase();
double divide (int a, int b)
{
if (b==0)
throw DivisionPorCero();
return double(a)/double(b);
}
• Manejar una excepción. Bloque:



try {
sentencias1
}
catch (nombreClase_1) {
sentencias2
}
catch (nombreClase_2) {
sentencias2
}
// no existe la sentencia “finally”


2 muy parecido a java, ¿qué habéis visto?
3 cualquier objeto, no es necesario que sea un objeto de clase heredera de otra que sea una excepción, es
decir, no necesario extends nombre_excepcion.
4 sin añadir new, es decir, no se usa throw new nombreClase();

Algoritmos y Estructuras de Datos, 2007/2008
Seminario de C++ – Sesión 3

6/12

• Funcionamiento del bloque try-catch:



1. Ejecutar las sentencias de sentencias1 normalmente.
2. Si se produce una excepción del tipo nombreClase, ejecutar sentencias2.

Estas sentencias contienen el código de manejo de excepciones.

try {
double d1, d2, d3;
d1= divide(3, 4);
d2= divide(5, 0);
d3= divide(1, 2);
}
catch (DivisionPorCero) {
cerr << "División por cero\n";
};


• Al contrario que en java, no se usa throws nombre_excepcion para indicar

que un método lanza excepciones del tipo nombre_excepcion.



• Manejar excepciones de cualquier tipo5:

try {
sentencias1
}
catch (...) {
sentencias2
}





• Ejemplo.
#include <iostream>
class DivisionPorCero {};
double divide (int a, int b)
{
if (b==0)
throw DivisionPorCero();
return double(a)/double(b);
}
main()
{
try {
cout << divide(3, 4) << '\n';
cout << divide(5, 0) << '\n';
cout << divide(1, 2) << '\n';
}
catch (DivisionPorCero) {
cerr << "División por cero\n";
}
cout << "Acaba\n";
}



• Probar:



1. Ejecutar la división por cero fuera del bloque try ... catch ...
2. Cambiar catch (DivisionPorCero) por catch (...)
3. Ejecutar una sentencia throw dentro del main()


5 en java, se haría catch con la clase exception.

Algoritmos y Estructuras de Datos, 2007/2008
Seminario de C++ – Sesión 3

7/12







3. Asertos

• Asertos: verificar una condición. Si se cumple, seguir normalmente. Si no, se
muestra la línea de código donde falló el programa y se interrumpe la ejecución.
assert ( condición booleana );

• La función assert() está definida en la librería <assert.h
  • Links de descarga
http://lwp-l.com/pdf1978

Comentarios de: SEMINARIO DE C++ (orientado a programadores java, pero no es parte del plan piloto, sólo para alumnos de AED) Sesión 3 (0)


No hay comentarios
 

Comentar...

Nombre
Correo (no se visualiza en la web)
Valoración
Comentarios...
CerrarCerrar
CerrarCerrar
Cerrar

Tienes que ser un usuario registrado para poder insertar imágenes, archivos y/o videos.

Puedes registrarte o validarte desde aquí.

Codigo
Negrita
Subrayado
Tachado
Cursiva
Insertar enlace
Imagen externa
Emoticon
Tabular
Centrar
Titulo
Linea
Disminuir
Aumentar
Vista preliminar
sonreir
dientes
lengua
guiño
enfadado
confundido
llorar
avergonzado
sorprendido
triste
sol
estrella
jarra
camara
taza de cafe
email
beso
bombilla
amor
mal
bien
Es necesario revisar y aceptar las políticas de privacidad