Transparencias () - Máster Universitario en Informática Gráfica

P R O
G
R A
M A C
I
Ó
N
Curso 0: Programación orientada a
objetos (POO)
Iván Alduán
([email protected])
ESCUELA TÉCNICA SUPERIOR DE INGENIERÍA INFORMÁTICA
1
P R O
G
R A
M A C
I
Ó
N
Introducción a C++
Introducción al entorno de Visual Studio
Programación de pequeños ejemplos en C++
ESCUELA TÉCNICA SUPERIOR DE INGENIERÍA INFORMÁTICA
3
Programación
P R O
G
R A
M A C
I
Ó
N
 La programación es el proceso de diseñar, escribir,
depurar y mantener el código fuente de programas
computacionales
 Ficheros fuente y programa o código fuente
 Pensados para que los comprendan los seres humanos
 Lenguaje de programación de alto nivel: C/C++, Java, C#, …
 Ficheros objeto, código objeto y compiladores
 compilador = traduce el programa fuente a su código objeto equivalente
(un fichero objeto por cada translation unit)
 Ficheros ejecutables, librerías y enlazadores
 Es necesario unir todos los ficheros objeto, más las librerías en un único
fichero ejecutable (o librería)
 Link o enlazador = combina todos los ficheros que forman nuestro
programa y crea el fichero ejecutable
ESCUELA TÉCNICA SUPERIOR DE INGENIERÍA INFORMÁTICA
4
Errores
P R O
G
R A
M A C
I
Ó
N
 Errores de sintaxis
 Son errores en el programa fuente. Pueden deberse a palabras
reservadas mal escritas, expresiones erróneas o incompletas
 El compilador nos dará una lista de errores de sintaxis
 Errores de enlazado
 El programa enlazador también puede encontrar errores,
funciones que no están definidas en ninguno de los ficheros
objetos ni en las librerías
 Puede que hayamos olvidado incluir alguna librería
 Errores de ejecución
 El programa terminará bruscamente
 Existen programas auxiliares para buscar estos errores, son los
llamados depuradores (debuggers)
 Errores de diseño
ESCUELA TÉCNICA SUPERIOR DE INGENIERÍA INFORMÁTICA
5
IDEs y Microsoft Visual Studio
P R O
G
R A
M A C
I
Ó
N
 Integrated Development Environment
 Proveen un marco de trabajo amigable con acceso a todas las
herramientas necesarias para desarrollar programas
 Editor de código
 Resaltado de sintaxis, indicador de errores, autocompletado
 Compilador y Enlazador automáticos
 Si fallan te indican el motivo con bastante exactitud
 Depurador
 Ayuda a caminar a través de nuestro programa para detectar
errores de ejecución: pila, breakpoint, watch
 Constructor de interfaces gráficas WYSIWIG (Plataforma .Net)
 Microsoft Visual Studio
 Versión Express gratuita (no plugins :/ )
 Versión Professional gratuita a través de DreamSpark
ESCUELA TÉCNICA SUPERIOR DE INGENIERÍA INFORMÁTICA
6
La función main en C++
P R O
G
R A
M A C
I
Ó
N
int main(int argc, char *argv[])
{
int numero;
numero = 2 + 2;
return 0;
}
 C++ es un superconjunto de C
 Aunque existen algunas diferencias entre ambos
 int main(): es la función que hace de punto de
entrada del programa. Todo programa en C++ debe
tener un función main
ESCUELA TÉCNICA SUPERIOR DE INGENIERÍA INFORMÁTICA
7
P R O
G
R A
M A C
I
Ó
N
Example 01 – Hello World
Comprobando que a todos nos funciona el IDE
ESCUELA TÉCNICA SUPERIOR DE INGENIERÍA INFORMÁTICA
8
Tipos de datos fundamentales C++
P R O
G
R A
M A C
I
Ó
N
 Heredados de C:
 void : no asociado a ningún tipo
 char : caracter
 int : entero
 float : número en coma flotante, precisión simple
 double : número en coma flotante, doble precisión
 Nuevos en C++:
 bool : tipo booleano
 wchar_t, char16_t, char32_t : caracter ancho (Unicode)
 Librería estándar de C++:
 std::string : cadenas de caracteres
ESCUELA TÉCNICA SUPERIOR DE INGENIERÍA INFORMÁTICA
9
Modificadores de tipos C++
P R O
G
R A
M A C
I
Ó
N
ESCUELA TÉCNICA SUPERIOR DE INGENIERÍA INFORMÁTICA
10
Operadores C++
P R O
G
R A
M A C
I
Ó
N
 Aritméticos:
 +, -, *, /, %,
 a++, ++a, a--,
: suma, resta, multiplicación, división, resto
--a : postincremento, preincremento, postdecremento
 Asignación:
: asigna a x el valor de evaluar <<expresión>>
+=, -=, *=, /= : suma, resta, multiplicación y división con asignación
 Ejemplo: a += b; es equivalente a: a = a + b;
 x = <<expresión>>

 Manejo de bits:
: and, or, xor y not binarios
 << , >> : desplazamiento a izquierda y a derecha
 &, |, ^, ~
 Lógicos:
 &&, ||, !
: and, or, not (devuelven un bool)
ESCUELA TÉCNICA SUPERIOR DE INGENIERÍA INFORMÁTICA
11
Operadores C++
P R O
G
R A
M A C
I
Ó
N
 Relacionales:
 >, >=, <, <=, ==, != : mayor, mayor o igual, menor, menor o igual, ..
(devuelven un bool)
 de Preproceso:
 #define, #line, #pragma ….
 de Puntero:
 Operadores de indirección (*) y de referencia (&)
 Manejo de memoria:
 new y delete
 Otros:
 :: , .* , ->* , ? : , sizeof(), typeid() ....
ESCUELA TÉCNICA SUPERIOR DE INGENIERÍA INFORMÁTICA
12
Operadores C++
P R O
G
R A
M A C
I
Ó
N
 Precedencia
 Prioridad de unos
operadores frente a otros
 Puede modificarse con
paréntesis
 Asociatividad
 define el orden de
ejecución para
operadores con idéntica
precedencia
ESCUELA TÉCNICA SUPERIOR DE INGENIERÍA INFORMÁTICA
13
Sentencias C++
P R O
G
R A
M A C
I
Ó
N
 Expresiones
 Declaración de variables <tipo> <identificador>;
 Asignación <variable> = <expresion>;
 Llamada a función <funcion>(<lista_parametros>);
 Bucles
 for (<inicializacion>; <condicion>; <incremento>) <sentencia>
 while (<condicion>) <sentencia>
 do <sentencia> while (<condicion>)
 Selección
 if (<condicion>) <sentencia1> else <sentencia2>
 switch (<variable) case <expresion>: <sentencia>
ESCUELA TÉCNICA SUPERIOR DE INGENIERÍA INFORMÁTICA
14
P R O
G
R A
M A C
I
Ó
N
Example 02 – Múltiplos de 3
Usando diferentes tipos de sentencias
ESCUELA TÉCNICA SUPERIOR DE INGENIERÍA INFORMÁTICA
15
Funciones C++
P R O
G
R A
M A C
I
Ó
N
 En C++ es obligatorio usar prototipos. Un prototipo es una
declaración de una función antes de ser utilizada dicha
función
 Las funciones se deben definir en alguna parte,
implementando su funcionalidad (cuerpo)
 Pueden estar en librerías externas, otros ficheros fuentes, etc
//Declaración de la función
int media(int, int);
...
//Definición de la función
int media(int a, int b)
{
int result;
result = (a + b)/2;
return result;
}
ESCUELA TÉCNICA SUPERIOR DE INGENIERÍA INFORMÁTICA
16
Funciones C++
P R O
G
R A
M A C
I
Ó
N
 La estructura de un programa en C++ quedaría así
ESCUELA TÉCNICA SUPERIOR DE INGENIERÍA INFORMÁTICA
17
Funciones C++ Recursividad
P R O
G
R A
M A C
I
Ó
N
 Una función es recursiva si durante su ejecución
tiene una llamada a si misma
 Se distingue entre:
 Recursividad directa
 Recursividad indirecta: varias se llaman unas a otras
formando ciclos
 Toda función recursiva ha de presentar al menos una
condición de terminación
 Ejemplos:
 Cálculo del factorial mediante recursividad directa
ESCUELA TÉCNICA SUPERIOR DE INGENIERÍA INFORMÁTICA
18
P R O
G
R A
M A C
I
Ó
N
Example 03 – Factorial
Usando funciones, el debugger y la pila de llamadas
ESCUELA TÉCNICA SUPERIOR DE INGENIERÍA INFORMÁTICA
19
Ámbito de variables y funciones
P R O
G
R A
M A C
I
Ó
N
 Una variable es global si se declara fuera de
cualquier función. Se puede acceder a ella desde
cualquier función
 Una variable global estática sólo es visible en la unidad de
compilación en la que se declara
 Las variables locales se declaran dentro de una
función o bloque, y solo son visibles desde el bloque
donde se declaran
 Los parámetros de una función son variables locales
 Una variable local estática conserva el valor entre distintas
llamadas a la función
ESCUELA TÉCNICA SUPERIOR DE INGENIERÍA INFORMÁTICA
20
Ámbito de variables y funciones
P R O
G
R A
M A C
I
Ó
N
/* Variables globales */
int i;
int j = 10;
float k, l;
static char m;
static int funcion_1()
{
/* Variables locales */
char d = ‘A’;
static int call = 0;
…
call++;
…
return call;
}
ESCUELA TÉCNICA SUPERIOR DE INGENIERÍA INFORMÁTICA
21
Conversión de tipos
P R O
G
R A
M A C
I
Ó
N
 Implícita:
 En expresiones el tipo mas bajo promociona al mas alto
long double > double > float > unsigned long long > long
long > unsigned long > long > unsigned int > int >
unsigned short > short > unsigned char > char
 En asignaciones el valor del lado derecho se convierte al
tipo de la variable de la izquierda
 Explicita (casting)
 (tipo) expresion
ESCUELA TÉCNICA SUPERIOR DE INGENIERÍA INFORMÁTICA
22
Constantes C++
P R O
G
R A
M A C
I
Ó
N
 Varias formas de declararlas:
 Usando la directiva del preprocesador #define:
#define MAX_SIZE 64
 Usando un tipo enumerado:
enum{
MAX_SIZE = 64,
};
 Usando const :
const int MAX_SIZE = 64;
ESCUELA TÉCNICA SUPERIOR DE INGENIERÍA INFORMÁTICA
23
Arrays C/C++
P R O
G
R A
M A C
I
Ó
N
 Son variables que contienen una colección
consecutiva de datos
 Se declaran entre corchetes, y su tamaño debe ser
fijado en tiempo de compilación
 Se accede a los elementos también entre corchetes.
Los índices comienzan en 0, y no hay comprobación
int a[10]; //array de 10 ints
float b[2][10] //array de 2 dimensiones
. . .
a[0] = 10;
b[1][4] = 5.3;
a[20] = 123; //esto no da error de compilación
ESCUELA TÉCNICA SUPERIOR DE INGENIERÍA INFORMÁTICA
24
Inicialización de Arrays
P R O
G
R A
M A C
I
Ó
N
 Al declarar un array se le puede dar valores iniciales a
sus elementos:
int
int
int
int
a[4] = {13, 1, 27, 1289};
b[] = {1, 3, 5, 7, 9};
c[4] = {23, 12}; //c[2] y c[3] sin inicializar
d[2] = {12, 24, 91, 103}; //warning
 Si no se especifica el tamaño, tomará el del número
de elementos inicializados.
 Si se inicializan menos del tamaño, los no
inicializados tendrán basura.
 Si se inicializan más del tamaño, el compilador dará
un aviso.
ESCUELA TÉCNICA SUPERIOR DE INGENIERÍA INFORMÁTICA
25
Punteros C/C++
P R O
G
R A
M A C
I
Ó
N
 Un puntero es una variable que representa una
posición de memoria que contiene un dato
 Se declaran anteponiendo un * al nombre de la
variable.
 Admiten el valor NULL (definido en cstdlib)
int *a; // puntero a entero
float *b; // puntero a flotante
char *c; // puntero a caracter
ESCUELA TÉCNICA SUPERIOR DE INGENIERÍA INFORMÁTICA
26
Operadores de punteros
P R O
G
R A
M A C
I
Ó
N
 Operaciones:
 El operador * dereferencia el puntero. Es decir, se accede
al valor apuntado
 El operador & devuelve la dirección de memoria donde se
encuentra una variable. Es decir se obtiene un puntero a la
variable
int a = 0;
int *b;
b = &a; // b apunta a la dirección donde está a
*b = 127; // se guarda 127 en la dir. apuntada por b
//En este punto la variable a tiene valor 127
ESCUELA TÉCNICA SUPERIOR DE INGENIERÍA INFORMÁTICA
27
Operadores de punteros
P R O
G
R A
M A C
I
Ó
N
 Operaciones:
 Los punteros se pueden sumar, restar, etc
 Esas operaciones se hacen en múltiplos del tamaño del
dato apuntado
int *a = . . . . //a apunta a algún lugar
a = a + 1; //ahora apunta sizeof(int) más adelante
// a apunta a la dir. del siguiente int en memoria
a = a + 4; //ahora apunta 4*sizeof(int) más adelante
ESCUELA TÉCNICA SUPERIOR DE INGENIERÍA INFORMÁTICA
28
Arrays y punteros
P R O
G
R A
M A C
I
Ó
N
 Los arrays se pueden comportar como punteros, y los
punteros como arrays
 Una variable de tipo array es un puntero al primer
elemento del array
 Un puntero al primer elemento de una colección
consecutiva puede usarse como un array
int a[16]; //array de 16 elementos
*a = 10; // Es lo mismo que a[0] = 10;
*(a + 3) = 20; // Es lo mismo que a[3] = 20;
int *b = (int *) malloc (8*sizeof(int));
//b es un puntero a un espacio de memoria en el
//que caben 8 ints
b[6] = 123; // Es lo mismo que *(b + 6) = 123;
ESCUELA TÉCNICA SUPERIOR DE INGENIERÍA INFORMÁTICA
29
Arrays y punteros
P R O
G
R A
M A C
I
Ó
N
 Diferencias:
 Un array tiene un tamaño asociado, un puntero no
 Un array es como un puntero constante, no se puede
cambiar el lugar al que apunta
 Un array está definido en memoria estática y un puntero
puede apuntar a memoria dinámica
int a[16]; //array de 16 elementos
int s1 = sizeof(a); //s1 valdrá 16*sizeof(int)
int *b = (int *) malloc (128*sizeof(int));
//b es un puntero a una colección de 128 int
int s2 = sizeof(b); //s2 valdrá 4 u 8, que es el
//tamaño de una dirección
ESCUELA TÉCNICA SUPERIOR DE INGENIERÍA INFORMÁTICA
30
Memoria dinámica
P R O
G
R A
M A C
I
Ó
N
 Stack o Pila (Memoria estática)
 Variables locales (dentro de un bloque)
 Va aumentando acumulando bloques de variables encima a
medida que entramos a más funciones
 El programa la gestiona automáticamente (FIFO)
 Tamaño muy limitado (1MB – 32MB)
 Heap o Montículo (Memoria dinámica)




Grueso de memoria no utilizado por ningún programa
Podemos reservar memoria dinámicamente
Enorme cantidad de memoria
Tenemos que gestionarla los programadores
ESCUELA TÉCNICA SUPERIOR DE INGENIERÍA INFORMÁTICA
31
malloc y free (C/C++)
P R O
G
R A
M A C
I
Ó
N
 Ejemplo:
int *a, *b; // punteros a enteros
//se reserva espacio en memoria para un entero
//a apunta a ese espacio de memoria
a = (int *) malloc (1*sizeof(int));
//se reserva espacio en memoria para 16 enteros
//b apunta a ese espacio de memoria
b = (int *) malloc (16*sizeof(int));
//se libera el espacio del primer malloc
free(a);
//se libera el espacio del segundo malloc
free(b);
ESCUELA TÉCNICA SUPERIOR DE INGENIERÍA INFORMÁTICA
32
new y delete (C++)
P R O
G
R A
M A C
I
Ó
N
 Para realizar esta administración de la memoria dinámica, C++
cuenta con dos operadores new y delete
 El operador new reserva memoria dinámica para cualquier tipo
 tipos primitivos (int, double)
 tipos definidos por el usuario (clases o registros)
 delete se encarga de liberar la memoria previamente reservada
 Pueden aplicarse para reservar elementos individuales o arrays
int *a, *b;
a = new int;
b = new int[100000000];
delete a;
delete[] b;
ESCUELA TÉCNICA SUPERIOR DE INGENIERÍA INFORMÁTICA
33
P R O
G
R A
M A C
I
Ó
N
Example 04 – Ordenación de un vector
Usando watch para inspeccionar el valor de punteros
ESCUELA TÉCNICA SUPERIOR DE INGENIERÍA INFORMÁTICA
34
Registros C++
P R O
G
R A
M A C
I
Ó
N
 Son tipos compuestos formados por elementos
heterogéneos
 Dentro del registro cada elemento tiene un
identificador y un tipo.
//Definición del registro
struct Complejo {
float real;
float imag;
};
//Declaración de variables del tipo registro
Complejo uncomplejo, otrocomplejo;
ESCUELA TÉCNICA SUPERIOR DE INGENIERÍA INFORMÁTICA
35
Registros C++
P R O
G
R A
M A C
I
Ó
N
 Para acceder a los elementos de un registro
estructura se utiliza el operador punto (.)
uncomplejo.real = 1.3;
uncomplejo.imag = 2.7;
 Si se trata de un puntero a registro se puede atajar
con el operador flecha (->)
Complejo *a = (Complejo *)malloc(sizeof(Complejo));
a->real = 2.4; //lo mismo que (*a).real = 2.4;
a->imag = 3.14; //lo mismo que (*a).imag = 3.14;
ESCUELA TÉCNICA SUPERIOR DE INGENIERÍA INFORMÁTICA
36
std::strings (C++)
P R O
G
R A
M A C
I
Ó
N
 En C++ si existe un tipo de datos para strings
 También se utilizan arrays de char acabados con el
caracter ‘\0’ como en C
 Una cadena de caracteres entre comillas dobles es un
inmediato que representa un string
#include<cstring>
std::string s = “Esto es un tipo cadena”;
char s1[] = “Hola”;
char *s2 = “Hola”;
char *s3[] = {‘H’, ‘o’, ‘l’, ‘a’, ‘\0’}
std::string s4(s1); // convertir a string
int n = s4.length(); // longitud de la cadena
ESCUELA TÉCNICA SUPERIOR DE INGENIERÍA INFORMÁTICA
37
Argumentos de funciones (C++)
P R O
G
R A
M A C
I
Ó
N
 Los argumentos por defecto siempre se pasan por valor
 Pasar un argumento por valor copia todo su contenido
 No se deben pasar nunca objetos pesados por valor
 Podríamos pasar punteros a los objetos
 Con paso por referencia la sintaxis es mucho más
amigable sin tener que aplicar los operadores de
punteros
 Internamente funcionan como punteros
//Ejemplo de paso de argumentos por referencia
void intercambia(int &a, int &b) {
int aux = a;
a = b;
b = aux;
}
int x = 10, y = 20;
Intercambia(x, y);
ESCUELA TÉCNICA SUPERIOR DE INGENIERÍA INFORMÁTICA
38
P R O
G
R A
M A C
I
Ó
N
Example 05 – Palíndromos
Operando con std::string
ESCUELA TÉCNICA SUPERIOR DE INGENIERÍA INFORMÁTICA
39
Espacios con nombre (C++)
P R O
G
R A
M A C
I
Ó
N
namespace mathlib
{
int max(int a, int b);
int min(int a, int b);
struct Vector {
float x, y, z;
};
...
}
 Nos ayudan a evitar problemas con identificadores
iguales en grandes proyectos
 Diferentes librerías puede que usen los mismos nombres
para cosas diferentes, de modo que resulta imposible
integrar esas librerías en la misma aplicación
ESCUELA TÉCNICA SUPERIOR DE INGENIERÍA INFORMÁTICA
40
Espacios con nombre (C++)
P R O
G
R A
M A C
I
Ó
N
 El nombre del espacio funciona como un prefijo para
las variables, funciones o clases declaradas en su
interior
 Para acceder a una de esas variables se tiene que
 Usar un especificador de ámbito (::)
 activar el espacio con nombre adecuado
mathlib::vector v;
int n = mathlib::max(10, 15);
using namespace mathlib;
Vector w;
int m = min(10, 15);
ESCUELA TÉCNICA SUPERIOR DE INGENIERÍA INFORMÁTICA
41
Librerías externas en Windows
P R O
G
R A
M A C
I
Ó
N
 Una librería es un conjunto de recursos (algoritmos)
prefabricados, que pueden ser utilizados por el
programador para realizar determinadas operaciones
 Windows:
 librerías estáticas (.lib) y librerías dinámicas (.dll)
 MSBUILD: librerías de importación (.lib)
 Necesitamos tres cosas
 Archivos de definición o includes
 Las librerías a importar dentro de nuestro programa (.lib)
 Si procede, que el programa tenga acceso a la librería dinámica
cuando entre en ejecución (.dll)
 Mismo directorio que el ejecutable
 PATH del sistema operativo
ESCUELA TÉCNICA SUPERIOR DE INGENIERÍA INFORMÁTICA
42
P R O
G
R A
M A C
I
Ó
N
Example 06 – GLUT Cube
Usando librerías externas y pintando gráficos 3D
ESCUELA TÉCNICA SUPERIOR DE INGENIERÍA INFORMÁTICA
43
Bibliografía recomendada
P R O
G
R A
M A C
I
Ó
N
 S.B. Lippman – C++ Primer (5th) – 2012
 B. Stroustrup – The C++ Programming Language (4th) – 2013
ESCUELA TÉCNICA SUPERIOR DE INGENIERÍA INFORMÁTICA
44
P R O
G
R A
M A C
I
Ó
N
Programación orientada a objetos (POO)
ESCUELA TÉCNICA SUPERIOR DE INGENIERÍA INFORMÁTICA
45
Programación Orientada a Objetos
P R O
G
R A
M A C
I
Ó
N
 La programación orientada a objetos es una forma de programar
que trata de encontrar una solución más intuitiva para la resolución
de problemas complejos
 Exige un cambio de mentalidad para diseñar aplicaciones y
programas informáticos ahora más complejos
 No buscamos directamente el encontrar la secuencia exacta de las
instrucciones necesarias para resolver el problema
 Queremos abstraernos a un nivel más conceptual para dividir el problema
en una serie de elementos que interaccionando entre sí den solución al
problema
 La idea básica de este tipo de programación es agrupar los datos y
los procedimientos para manejarlos en entidades únicas con un
significado a las que llamaremos objetos
 Un programa es un objeto, que a su vez está formado de otros
objetos que interactúan entre sí
ESCUELA TÉCNICA SUPERIOR DE INGENIERÍA INFORMÁTICA
46
Objeto
P R O
G
R A
M A C
I
Ó
N
 Un objeto es una unidad con cierto significado que
engloba en sí mismo:
 Un conjunto de datos que definen su estado
 Los procedimientos necesarios para el tratamiento de esos
datos con facilidad
 Ejemplos de objetos del inundo real son: pasajero,
asiento, avión, vuelo, aeropuerto
 Por ejemplo, los atributos de un pasajero incluyen el nombre, la
edad, el sexo, la fecha de nacimiento, la dirección, etc
 El comportamiento es el conjunto de cosas que puede hacer un
objeto; por ejemplo, un pasajero puede estudiar, trabajar,
comer, dormir, etc
ESCUELA TÉCNICA SUPERIOR DE INGENIERÍA INFORMÁTICA
47
Objeto
P R O
G
R A
M A C
I
Ó
N
 Posible ejemplo de un objeto dentro de una aplicación
encargada de gestionar unos cines
 Otros objetos en la aplicación podrían ser cine,
empleado, sala, proyector, butaca, espectador, entrada
ESCUELA TÉCNICA SUPERIOR DE INGENIERÍA INFORMÁTICA
48
Objeto: conceptos
P R O
G
R A
M A C
I
Ó
N
 Propiedades o atributos: Características o variables
que definen a un objeto
 Métodos: Funciones disponibles en el objeto para
manipular o modificar los atributos del mismo
 Mensaje: El mensaje es el modo en el que se
comunican los objetos entre sí
 En realidad, esto no es mas que una llamada a un método
de un determinado objeto
ESCUELA TÉCNICA SUPERIOR DE INGENIERÍA INFORMÁTICA
49
Programa OO vs OP
P R O
G
R A
M A C
I
Ó
N
 El resultado final del proceso es un programa de computadora
que contiene características que representan algunos de los
objetos del mundo real que son parte del suceso
ESCUELA TÉCNICA SUPERIOR DE INGENIERÍA INFORMÁTICA
50
Ventajas
P R O
G
R A
M A C
I
Ó
N
 Ventajas de la programación orientada a objetos
 Diseños más cercanos al mundo real
 Más fáciles de diseñar y mantener
 Facilidad de comunicación entre todos los roles implicados
en el desarrollo: usuarios, clientes, analistas, diseñadores,
programadores
 Facilita la reutilización de código ya que cada objeto tiene
significado propio
 Cada objeto es independiente del resto
 Ejemplo: Una clase Vector3 la podremos reutilizar en todas
nuestras aplicaciones de gráficos
ESCUELA TÉCNICA SUPERIOR DE INGENIERÍA INFORMÁTICA
51
Clases
P R O
G
R A
M A C
I
Ó
N
 Una clase define un patrón para construir objetos
 Es importante distinguir entre objetos y clases
 La clase es simplemente una declaración, patrón o tipo
 Los objetos son los ejemplares concretos de una clase.
Cuando creamos un ejemplar tenemos que especificar la
clase a partir de la cual se creará
 Por ejemplo, un objeto de la clase película sería Toy Story
ESCUELA TÉCNICA SUPERIOR DE INGENIERÍA INFORMÁTICA
52
Clases en C++
P R O
G
R A
M A C
I
Ó
N
 Las clases C++ permiten definir nuevos tipos de datos
 Cada clase es un nuevo tipo
 Cada elemento de la clase se caracteriza por ciertos valores
y las operaciones disponibles para crear dichos elementos,
modificarlos y destruirlo
 Podemos establecer un paralelismo entre los tipos de
datos vistos hasta el momento (int, char, array, struct,
…) y las clases
 Ambos son tipos
 Pueden declararse elementos de ese tipo
 En los tipos por defecto los llamábamos variables
 En el caso de una clase los llamaremos instancias u objetos
ESCUELA TÉCNICA SUPERIOR DE INGENIERÍA INFORMÁTICA
53
Clases en C++
P R O
G
R A
M A C
I
Ó
N
 Características fundamentales de las clases en C++
 Nombre de la clase. Sirve para identificar a todos los
objetos que tengan unas determinadas características
 Conjunto de atributos. Datos miembro. El valor de los
atributos representan el estado de cada objeto.
 Conjunto de métodos. Funciones miembro. Permite que
los objetos cambien de estado, dependiendo del estado
anterior que tuviera el objeto.
 Niveles de acceso para proteger ciertos miembros de la
clase. Normalmente, se definirán como ocultos (privados)
los atributos y visibles (públicos) los métodos.
ESCUELA TÉCNICA SUPERIOR DE INGENIERÍA INFORMÁTICA
54
Declaración de clases en C++
P R O
G
R A
M A C
I
Ó
N
ESCUELA TÉCNICA SUPERIOR DE INGENIERÍA INFORMÁTICA
55
Paso de mensajes
P R O
G
R A
M A C
I
Ó
N
 Una vez creados los objetos, podemos trabajar con ellos. Si
queremos que un determinado objeto ejecute un método,
utilizamos el operador punto (•).
 A esto se le conoce como paso de mensajes.
 Cada paso de mensaje provoca la ejecución del correspondiente
método definido en la clase del objeto receptor
 Cada objeto entiende tantos mensajes como métodos estén definidos
en su clase
ESCUELA TÉCNICA SUPERIOR DE INGENIERÍA INFORMÁTICA
56
Ocultación / Encapsulamiento
P R O
G
R A
M A C
I
Ó
N
 La clave de la programación orientada a objetos es el
encapsulamiento de todo el código y detalles de
implementación bajo interfaces de manejo sencillo
 La definición de una clase en C++ viene dada por:
 Un archivo de cabecera (.h)
 Define la interfaz de la clase de forma clara, es decir, qué métodos
ofrece el módulo definido, sin detalles de implementación
 Un archivo fuente (.cpp)
 Define los detalles de implementación de la clase
 Inclusión de su correspondiente fichero de cabecera (#include)
 Definición de funciones declaradas y no declaradas en el fichero
de cabecera
ESCUELA TÉCNICA SUPERIOR DE INGENIERÍA INFORMÁTICA
57
Especificadores de acceso
P R O
G
R A
M A C
I
Ó
N
 Dentro de la lista de miembros, cada miembro puede
tener diferentes niveles de acceso
class <identificador de clase>
{
public:
<lista de miembros>
private:
<lista de miembros>
protected:
<lista de miembros>
};
 Public: miembros accesibles desde cualquier parte
 Private: sólo son accesibles por la propia clase
 Protected: nos faltan conocimientos para entenderlo
ESCUELA TÉCNICA SUPERIOR DE INGENIERÍA INFORMÁTICA
58
Especificadores de acceso
P R O
G
R A
M A C
I
Ó
N
 Por lo general
 Los atributos deben ser privados
 Los métodos o funciones miembro deben ser públicas
 A través del objeto de una clase sólo se puede acceder a lo que está
declarado como público en la clase
 Lo privado solo puede ser manipulado internamente desde el código
de los métodos
ESCUELA TÉCNICA SUPERIOR DE INGENIERÍA INFORMÁTICA
59
El puntero this
P R O
G
R A
M A C
I
Ó
N
 Todos los objetos de una clase comparten la misma
copia de las funciones de esa clase
 ¿cómo hace una función miembro para referirse a un dato
de un objeto en concreto?
 La respuesta es: usando el puntero this
 cada objeto tiene asociado un puntero a si mismo que se
puede usar para manejar sus miembros
 generalmente su uso es transparente al programador, pero
a veces es necesario invocarlo de manera explícita
void pareja::Guarda(int a_input, int b) {
a = a_input; // equivale a this->a = a_input;
this->b = b;
}
ESCUELA TÉCNICA SUPERIOR DE INGENIERÍA INFORMÁTICA
60
Diseño conceptual
P R O
G
R A
M A C
I
Ó
N
 Para representar gráficamente las clases y objetos, se
utilizan diagramas conceptuales basados en UML
(Lenguaje de Modelado Unificado)
ESCUELA TÉCNICA SUPERIOR DE INGENIERÍA INFORMÁTICA
61
Resumen
P R O
G
R A
M A C
I
Ó
N
 Las instancias de un tipo cualquiera se denominan variables,
mientras que las instancias de una clase se denominan
objetos
 Los atributos describen el estado de un objeto. Un atributo
consta de dos partes: nombre del atributo y valor.
 Los métodos describen el comportamiento de los objetos de
una clase. Representan las operaciones que se pueden
realizar con los objetos de la clase. La ejecución de un método
puede conducir a cambiar el estado del objeto.
 Los objetos se manipulan mediante el paso de mensajes. Para
ejecutar un método asociado a un objeto, se realiza una
acción que se conoce como “envío de mensajes”.
 Se denomina encapsulamiento al ocultamiento del estado, es
decir, de los datos miembro, de un objeto
 Las operaciones y datos visibles desde el exterior de la clase es lo que
se denomina interfaz de la clase
ESCUELA TÉCNICA SUPERIOR DE INGENIERÍA INFORMÁTICA
62
El poder de la POO
P R O




G
R A
M A C
I
Ó
N
Constructores y destructores
Sobrecarga de operadores y métodos
Métodos estáticos
Herencia
 Interfaces
 Clases abstractas
 Funciones virtuales
 Polimorfismo
 Plantillas
 Excepciones
ESCUELA TÉCNICA SUPERIOR DE INGENIERÍA INFORMÁTICA
63
Constructores
P R O
G
R A
M A C
I
Ó
N
 Los constructores son funciones miembro especiales
que sirven para inicializar un objeto
 Tienen el mismo nombre que la clase, no retornan
ningún valor y no pueden ser heredados
 Por norma general deben ser públicos ya que
siempre se usan desde el exterior de la clase
 en un patrón de diseño singleton precisamente nos
interesa lo contrario, que el constructor esté oculto
 Si no declaramos ningún constructor, el compilador
lo hará por nosotros creando uno por defecto
ESCUELA TÉCNICA SUPERIOR DE INGENIERÍA INFORMÁTICA
64
Constructores
P R O
G
R A
M A C
I
Ó
N
 Ejemplo:
class pareja {
public:
// Constructor
pareja(int a2, int b2);
// Funciones miembro de la clase "pareja"
void Lee(int &a2, int &b2);
void Guarda(int a2, int b2);
private:
// Datos miembro de la clase "pareja"
int a, b;
public:
};
pareja::pareja(int a2, int b2) {
a = a2;
b = b2;
}
ESCUELA TÉCNICA SUPERIOR DE INGENIERÍA INFORMÁTICA
65
Constructores
P R O
G
R A
M A C
I
Ó
N
 Cuando se use un constructor sin parámetros para
declarar un objeto no se deben escribir los paréntesis
 error frecuente cuando se empiezan a usar clases
 Si un constructor requiere argumentos, es obligatorio
suministrarlos
pareja par1(12,43);
pareja par2(45,34);
pareja par1(); //ERROR -> El compilador piensa que es un
//prototipo de una función
pareja par1;
ESCUELA TÉCNICA SUPERIOR DE INGENIERÍA INFORMÁTICA
66
Constructores
P R O
G
R A
M A C
I
Ó
N
 Hay un modo más seguro de inicializar los datos
miembros de los objetos en los constructores
 Inicializadores: Cada inicializador consiste en el nombre de
la variable miembro a inicializar, seguida de la expresión
que se usará para inicializarla entre paréntesis
pareja::pareja(int a2, int b2) : a(a2), b(b2) {}
 Pregunta:
 ¿Qué pasa si dentro de nuestra clase tenemos como
atributo un objeto sin constructor por defecto?
 ¿Eficiencia?
ESCUELA TÉCNICA SUPERIOR DE INGENIERÍA INFORMÁTICA
67
Constructores
P R O
G
R A
M A C
I
Ó
N
 Sobrecarga de constructores
 podemos definirse varios constructores para cada clase
pareja(int a2, int b2) : a(a2), b(b2) {}
pareja() : a(0), b(0) {}
 Argumentos por defecto
 reducir el número de constructores necesarios
pareja(int a2=0, int b2=0) : a(a2), b(b2) {}
ESCUELA TÉCNICA SUPERIOR DE INGENIERÍA INFORMÁTICA
68
Constructores
P R O
G
R A
M A C
I
Ó
N
 Constructor copia
 crea un objeto a partir de otro objeto existente
 un argumento que es una referencia a un objeto de su
misma clase
 si no se define, el compilador crea uno por defecto
pareja(const pareja &p);
pareja::pareja(const pareja &p) : a(p.a), b(p.b) {}
 Asignación de objetos
 copia los valores de los datos miembro
pareja par1(12, 32), par2;
par2 = par1;
ESCUELA TÉCNICA SUPERIOR DE INGENIERÍA INFORMÁTICA
69
Destructores
P R O
G
R A
M A C
I
Ó
N
 Los destructores son funciones miembro especiales
que sirven para definir cómo se elimina un objeto de
una determinada clase
 Tienen el mismo nombre que la clase, pero con el
símbolo ~ delante, no retornan ningún valor y no
pueden ser heredados
 En general, será necesario definir un destructor
cuando nuestra clase tenga datos miembro de tipo
puntero
 Pregunta:
 ¿Tiene sentido la sobrecarga de destructores?
ESCUELA TÉCNICA SUPERIOR DE INGENIERÍA INFORMÁTICA
70
Ejemplo: Clase cadena
P R O
G
class cadena {
public:
cadena(char *c);
cadena(const cadena &);
~cadena();
R A
M A C
I
Ó
N
// ¿Por qué es necesario definirlo?
// ¿Por qué es necesario definirlo?
void Set(char *dest);
char* Get();
private:
char *cad; // cadena de caracteres
};
cadena::cadena(char *c) {
cad = new char[strlen(c)+1];
strcpy(cad, c); // Almacena la cadena
}
…
ESCUELA TÉCNICA SUPERIOR DE INGENIERÍA INFORMÁTICA
71
Ejemplo: Clase cadena
P R O
G
R A
M A C
I
Ó
N
…
cadena::~cadena() {
delete[] cad; // Libera la memoria reservada a cad
}
cadena::cadena(const cadena &c) {
if(&c == this) {
cout << "Sí, soy yo." << endl;
this->cad = c.cad;
}
else {
cout << "No, no soy yo." << endl;
this->cad = new char[strlen(c.cad)+1];
strcpy(this->cad, c.cad);
}
return c;
}
ESCUELA TÉCNICA SUPERIOR DE INGENIERÍA INFORMÁTICA
72
Operadores sobrecargados
P R O
G
R A
M A C
I
Ó
N
 Podemos redefinir cualquier operando aplicado a
una clase para que funcione como nosotros
deseemos
 Cuando se sobrecargan operadores en el interior de
una clase se asume que un operando es el propio
objeto de la clase por lo que no hay que declararlo
 Cuando nuestra clase tenga punteros es posible que
necesitemos sobrecargar el operador asignación (=)
 Pensar en los problemas anteriores del constructor copia
por defecto
ESCUELA TÉCNICA SUPERIOR DE INGENIERÍA INFORMÁTICA
73
Sobrecarga de operadores
P R O
G
R A
M A C
I
Ó
N
class Tiempo {
public:
Tiempo(int h=0, int m=0) : hora(h), minuto(m) {}
Tiempo operator+(const Tiempo &h);
Tiempo operator*(const Tiempo &h); ¿tiene sentido?
private:
int hora;
int minuto;
};
Tiempo Tiempo::operator+(const Tiempo &h) {
Tiempo temp;
temp.minuto = minuto + h.minuto;
temp.hora = hora + h.hora;
if(temp.minuto >= 60) {
temp.minuto -= 60;
temp.hora++;
}
return temp;
}
ESCUELA TÉCNICA SUPERIOR DE INGENIERÍA INFORMÁTICA
74
Operadores sobrecargados
P R O
G
R A
M A C
I
Ó
N
 Problema:
 ¿Cómo sobrecargamos un operador unitario sufijo?
class Tiempo {
...
Tiempo& operator++();
...
};
Tiempo& Tiempo::operator++() {
minuto++;
while(minuto >= 60) {
minuto -= 60;
hora++;
}
return *this;
}
Tiempo t1;
++t1;
¿t1++;?
ESCUELA TÉCNICA SUPERIOR DE INGENIERÍA INFORMÁTICA
75
Operadores sobrecargados
P R O
G
R A
M A C
I
Ó
N
 Problema:
 ¿Cómo sobrecargamos el operador unitario sufijo?
 no hay forma de decirle al compilador cuál de las dos
modalidades del operador estamos sobrecargando, así que
los compiladores usan una regla: si se declara un parámetro
para un operador ++ ó – se sobrecargará la forma sufija del
operador
Tiempo Tiempo::operator++(int) {
Tiempo temp(*this); // Constructor copia
minuto++;
while(minuto >= 60) {
minuto -= 60;
hora++;
}
return temp;
}
ESCUELA TÉCNICA SUPERIOR DE INGENIERÍA INFORMÁTICA
76
Métodos sobrecargados
P R O
G
R A
M A C
I
Ó
N
 Sobrecarga de métodos
 Las funciones miembros de las clases también pueden
sobrecargarse
 Argumentos por defecto
 En las funciones miembros de las clases también pueden
usarse parámetros con valores por defecto
void Vector3D::Asignar(float xi, float yi=0, float zi=0) {
x = xi;
y = yi;
z = zi;
}
void Vector3D::Asignar(const Vector3D &p) {
Asignar(p.x, p.y, p.z);
}
ESCUELA TÉCNICA SUPERIOR DE INGENIERÍA INFORMÁTICA
77
Sistema de protección
P R O
G
R A
M A C
I
Ó
N
 Especificadores de acceso
 public:
private:
protected:
 Declaraciones friend
 El modificador "friend" puede aplicarse a clases o funciones
para inhibir el sistema de protección
 Las relaciones de "amistad" entre clases son parecidas a las
amistades entre personas:
 la amistad no puede transferirse, si A es amigo de B, y B es
amigo de C, esto no implica que A sea amigo de C
 la amistad no puede heredarse. Si A es amigo de B, y C es una
clase derivada de B, A no es amigo de C
 la amistad no es simétrica. Si A es amigo de B, B no tiene por
qué ser amigo de A
ESCUELA TÉCNICA SUPERIOR DE INGENIERÍA INFORMÁTICA
78
Sistema de protección
P R O
G
R A
M A C
I
Ó
N
 Ejemplo: funciones amigas externas
class A {
public:
A(int i=0) : a(i) {}
private:
int a;
friend void Ver(A); // "Ver" es amiga de la clase A
};
void Ver(A Xa) {
// La función Ver puede acceder a miembros privados
// de la clase A, ya que ha sido declarada "amiga" de A
cout << Xa.a << endl;
}
ESCUELA TÉCNICA SUPERIOR DE INGENIERÍA INFORMÁTICA
79
Sistema de protección
P R O
G
R A
M A C
I
Ó
N
 Ejemplo: funciones amigas en otras clases
class A; // Declaración previa (forward)
class B {
public:
B(int i=0) : b(i) {}
void Ver() { cout << b << endl; }
bool EsMayor(A Xa); // Compara b con a
private:
int b;
};
class A {
public:
A(int i=0) : a(i) {}
void Ver() { cout << a << endl; }
private:
// Función amiga tiene acceso a miembros privados de la clase A
friend bool B::EsMayor(A Xa);
int a;
};
ESCUELA TÉCNICA SUPERIOR DE INGENIERÍA INFORMÁTICA
80
Sistema de protección
P R O
G
R A
M A C
I
Ó
N
 Ejemplo: clases amigas
/* Clase para elemento de lista enlazada */
class Elemento {
public:
Elemento(int t);
int Tipo() { return tipo;}
private:
int tipo;
Elemento *sig; // siguiente elemento
friend class Lista; // amistad con lista
};
/* Clase para lista enlazada de números*/
class Lista {
. . .
}
ESCUELA TÉCNICA SUPERIOR DE INGENIERÍA INFORMÁTICA
81
Modificadores de miembros
P R O
G
R A
M A C
I
Ó
N
 Funciones miembro inline
 El código generado para esa función cuando el programa se
compila, se inserta en todos los punto donde se invoca a la
función, en lugar de hacerlo en otro lugar y hacer llamadas
 Hay dos maneras de declarar una función como inline:
 Las funciones que se definen dentro de la declaración de la clase
son inline implícitamente
 La otra forma es hacerlo explícitamente
class Ejemplo {
public:
Ejemplo(int a = 0);
private:
int A;
};
inline Ejemplo::Ejemplo(int a) : A(a) {}
ESCUELA TÉCNICA SUPERIOR DE INGENIERÍA INFORMÁTICA
82
Modificadores de miembros
P R O
G
R A
M A C
I
Ó
N
 Funciones miembro const
 Cuando una función miembro no modifique el valor de
ningún dato de la clase, podemos y debemos declararla
como constante
 si la función intenta modificar el objeto el compilador
generará un error
class Ejemplo2 {
public:
Ejemplo2(int a = 0) : A(a) {}
void Modifica(int a) { A = a; } // Error si se declara constante
int Lee() const { return A; }
private:
int A;
};
ESCUELA TÉCNICA SUPERIOR DE INGENIERÍA INFORMÁTICA
83
Modificadores de miembros
P R O
G
R A
M A C
I
Ó
N
 Otros usos de const
 valores de retorno constantes de las funciones
 paso de parámetros constantes a funciones
const Vector Vector::operator+( const Vector &other ) const {
Vector result;
result.x = this->x + other.x;
result.y = this->y + other.y;
result.z = this->z + other.z;
return result;
}
ESCUELA TÉCNICA SUPERIOR DE INGENIERÍA INFORMÁTICA
84
Modificadores de miembros
P R O
G
R A
M A C
I
Ó
N
 Miembros static de una clase
 Son miembros que no dependen de un objeto o instancia
concreto sino que funcionan a nivel de clase
 En el caso de los atributos static sólo existirá una copia que
compartirán todos los objetos de la misma clase
 Es necesario inicializar los datos estáticos de una clase
 Las funciones static no pueden acceder a los miembros de
los objetos, sólo pueden acceder a los datos miembro de la
clase que sean static
ESCUELA TÉCNICA SUPERIOR DE INGENIERÍA INFORMÁTICA
85
Modificadores de miembros
P R O
G
R A
M A C
I
Ó
N
 Ejemplo:
class Singleton {
public:
static Singleton* Instance();
private:
Singleton();
Singleton(const Singleton &);
Singleton &operator= (const Singleton &);
static Singleton* pinstance;
};
Singleton* Singleton::pinstance = NULL;// Inicializa el miembro static
Singleton* Singleton::Instance () {
if (pinstance == NULL)
pinstance = new Singleton;
// ¿Es la primera llamada?
// Creamos la instancia
return pinstance;
}
Singleton *obj = Singleton::Instance();
ESCUELA TÉCNICA SUPERIOR DE INGENIERÍA INFORMÁTICA
86
P R O
G
R A
M A C
I
Ó
N
Example 07 – GLUT orientado a objetos
ESCUELA TÉCNICA SUPERIOR DE INGENIERÍA INFORMÁTICA
87
Herencia
P R O
G
R A
M A C
I
Ó
N
 Nos permite crear nuevas clases a partir de clases
existentes, conservando las propiedades de la clase
original y añadiendo otras nuevas
 La nueva clase obtenida se conoce como clase
derivada, y las clases a partir de las cuales se deriva,
clases base
 cada clase derivada puede usarse como clase base para
obtener una nueva clase derivada
 y cada clase derivada puede serlo de una o más clases base
ESCUELA TÉCNICA SUPERIOR DE INGENIERÍA INFORMÁTICA
88
Herencia
P R O
G
R A
M A C
I
Ó
N
 Esto nos va a permitir crear jerarquías de clases tan
complejas como nos sea necesario
ESCUELA TÉCNICA SUPERIOR DE INGENIERÍA INFORMÁTICA
89
Herencia
P R O
G
R A
M A C
I
Ó
N
 Un ejemplo muy común es de las personas
 todas las personas tienen propiedades comunes, nombre,
fecha de nacimiento, género, estado civil, etc.
 dividimos a todas las personas en dos grandes clases:
empleados y estudiantes
 los ingresos por nómina son exclusivos de los empleados
 la nota media del curso es exclusiva de los estudiantes
 ahora podemos clasificar a los empleados en ejecutivos y
comerciales ….
ESCUELA TÉCNICA SUPERIOR DE INGENIERÍA INFORMÁTICA
90
Herencia
P R O
G
R A
M A C
I
Ó
N
 Ahora podemos ver las ventajas de disponer de una
jerarquía completa de clases
 Cada vez que creemos un objeto de cualquier tipo
derivado este tendrá las propiedades de todos sus tipos
base
 Siempre podremos crear nuevas clases para resolver
nuevas situaciones
 Podemos aplicar procedimientos genéricos a una clase en
concreto sin tener en cuenta que tipo de subclase es
ESCUELA TÉCNICA SUPERIOR DE INGENIERÍA INFORMÁTICA
91
Herencia
P R O
G
R A
M A C
I
Ó
N
 Ejemplo:
// Clase base Persona:
class Persona {
public:
Persona(char *n, int e);
const char *LeerNombre(char *n) const;
int LeerEdad() const;
void CambiarNombre(const char *n);
void CambiarEdad(int e);
protected:
char nombre[40];
int edad;
};
// Clase derivada Empleado:
class Empleado : public Persona {
public:
Empleado(char *n, int e, float s);
float LeerSalario() const;
void CambiarSalario(const float s);
protected:
float salarioAnual;
};
ESCUELA TÉCNICA SUPERIOR DE INGENIERÍA INFORMÁTICA
92
Herencia
P R O
G
R A
M A C
I
Ó
N
 Para cada clase base podemos definir dos tipos de
acceso, public o private. Si no se especifica ninguno de
los dos, por defecto se asume que es private
 public: los miembros heredados de la clase base conservan el
tipo de acceso con que fueron declarados en ella
 private: todos los miembros heredados de la clase base pasan a
ser miembros privados en la clase derivada
 Usar el acceso protected nos permite que los datos sean
inaccesibles desde el exterior de las clases, pero a la vez,
permite que sean accesibles desde las clases derivadas
ESCUELA TÉCNICA SUPERIOR DE INGENIERÍA INFORMÁTICA
93
Herencia
P R O
G
R A
M A C
I
Ó
N
 Constructores en clases derivadas
 Cuando se crea un objeto de una clase derivada, primero
se invoca al constructor de la clase base y a continuación al
constructor de la clase derivada
 Si el constructor base no tiene parámetros la llamada se
realiza de forma automática
 Si el constructor base necesita parámetros, tenemos que
encargarnos nosotros de llamar al constructor base
ESCUELA TÉCNICA SUPERIOR DE INGENIERÍA INFORMÁTICA
94
Herencia
P R O
G
R A
M A C
I
Ó
N
 Ejemplo:
class ClaseA {
public:
ClaseA(int a) : datoA(a) {
cout << "Constructor de A" << endl;
}
int LeerA() const { return datoA; }
protected:
int datoA;
};
class ClaseB : public ClaseA {
public:
ClaseB(int a, int b) : ClaseA(a), datoB(b) { (1)
cout << "Constructor de B" << endl;
}
int LeerB() const { return datoB; }
protected:
int datoB;
};
ESCUELA TÉCNICA SUPERIOR DE INGENIERÍA INFORMÁTICA
95
Herencia
P R O
G
R A
M A C
I
Ó
N
 Destructores en clases derivadas
 Cuando se destruye un objeto de una clase derivada,
primero se invoca al destructor de la clase derivada, si
existen objetos miembro a continuación se invoca a sus
destructores y finalmente al destructor de la clase base
class ClaseB : public ClaseA {
public:
ClaseB() : datoB(20) {
cout << "Constructor de B" << endl;
}
~ClaseB() { cout << "Destructor de B" << endl; }
int LeerB() const { return datoB; }
protected:
int datoB;
};
ESCUELA TÉCNICA SUPERIOR DE INGENIERÍA INFORMÁTICA
96
Polimorfismo
P R O
G
R A
M A C
I
Ó
N
 En una clase derivada se puede definir una función
que ya existía en la clase base, esto se conoce como
"overriding", o superposición de una función
 La definición de la función en la clase derivada oculta la
definición previa en la clase base
 Podemos acceder a la función de la clase base mediante
una sintaxis un tanto especial
 Superposición
 Cuando se superpone una función, se ocultan todas las
funciones con el mismo nombre en la clase base
ESCUELA TÉCNICA SUPERIOR DE INGENIERÍA INFORMÁTICA
97
Polimorfismo
P R O
G
R A
M A C
I
Ó
N
 Ejemplo:
class ClaseA {
public:
ClaseA() : datoA(10) {}
int LeerA() const { return datoA; }
void Mostrar() { cout << "a = " << datoA << endl; }
protected:
int datoA;
};
class ClaseB : public ClaseA {
public:
ClaseB() : datoB(20) {}
int LeerB() const { return datoB; }
void Mostrar() { cout << "a = " << datoA << ", b = “ << datoB << endl; }
protected:
int datoB;
};
ClaseB objeto;
objeto.Mostrar();
objeto.ClaseA::Mostrar();
ESCUELA TÉCNICA SUPERIOR DE INGENIERÍA INFORMÁTICA
98
Polimorfismo
P R O
G
R A
M A C
I
Ó
N
 C++ nos permite acceder a objetos de una clase
derivada usando un puntero a la clase base
 Por supuesto, sólo podremos acceder a datos y
funciones que existan en la clase base, los datos y
funciones propias de los objetos de clases derivadas
serán inaccesibles
 Con lo que hemos visto hasta ahora, si accedemos a
objetos de una clase derivada usando un puntero a la
clase base, se ejecuta el código de la clase base
ESCUELA TÉCNICA SUPERIOR DE INGENIERÍA INFORMÁTICA
99
Polimorfismo
P R O
G
R A
M A C
I
Ó
N
 Ejemplo:
class Persona {
public:
Persona(char *n) { strcpy(nombre, n); }
void VerNombre() { cout << nombre << endl; }
protected:
char nombre[30];
};
class Empleado : public Persona {
public:
Empleado(char *n) : Persona(n) {}
void VerNombre() { cout << "Emp: " << nombre << endl; }
};
class Estudiante : public Persona {
public:
Estudiante(char *n) : Persona(n) {}
void VerNombre() { cout << "Est: " << nombre << endl; }
};
Persona *Pepito = new Estudiante("Jose");
Persona *Carlos = new Empleado("Carlos");
ESCUELA TÉCNICA SUPERIOR DE INGENIERÍA INFORMÁTICA
100
Polimorfismo
P R O
G
R A
M A C
I
Ó
N
 Sería mucho más interesante que cuando se invoque
a una función que se superpone en la clase derivada,
se llame a ésta última función, la de la clase derivada
 Esto se consigue mediante el uso de funciones
virtuales
 cuando en una clase declaramos una función como virtual,
y la superponemos en alguna clase derivada, al invocarla
usando un puntero de la clase base, se ejecutará la versión
de la clase derivada
ESCUELA TÉCNICA SUPERIOR DE INGENIERÍA INFORMÁTICA
101
Polimorfismo
P R O
G
R A
M A C
I
Ó
N
 Ejemplo:
class Persona {
public:
Persona(char *n) { strcpy(nombre, n); }
virtual void VerNombre() { cout << nombre << endl; }
protected:
char nombre[30];
};
class Empleado : public Persona {
public:
Empleado(char *n) : Persona(n) {}
void VerNombre() { cout << "Emp: " << nombre << endl; }
};
class Estudiante : public Persona {
public:
Estudiante(char *n) : Persona(n) {}
void VerNombre() { cout << "Est: " << nombre << endl; }
};
Persona *Pepito = new Estudiante("Jose");
Persona *Carlos = new Empleado("Carlos");
ESCUELA TÉCNICA SUPERIOR DE INGENIERÍA INFORMÁTICA
102
Polimorfismo
P R O
G
R A
M A C
I
Ó
N
 También funciona con referencias
Estudiante Pepito("Jose");
Empleado Carlos("Carlos");
Persona &rPepito = Pepito; // Referencia como Persona
Persona &rCarlos = Carlos; // Referencia como Persona
rCarlos.VerNombre();
rPepito.VerNombre();
 Una vez que una función es declarada como virtual,
lo seguirá siendo en las clases derivadas, es decir, la
propiedad virtual se hereda
ESCUELA TÉCNICA SUPERIOR DE INGENIERÍA INFORMÁTICA
103
Polimorfismo
P R O
G
R A
M A C
I
Ó
N
1. Supongamos que tenemos una estructura de clases en la que
en alguna de las clases derivadas exista un destructor…
2. si destruimos un objeto referenciado mediante un puntero a
la clase base, y el destructor no es virtual, estaremos
llamando al destructor de la clase base…
3. ¡Esto puede ser desastroso!
 Destructores virtuales
 debemos respetar siempre ésta regla: si en una clase
existen funciones virtuales, el destructor debe ser virtual
ESCUELA TÉCNICA SUPERIOR DE INGENIERÍA INFORMÁTICA
104
Polimorfismo
P R O
G
R A
M A C
I
Ó
N
1. accedemos a un objeto de una clase derivada usando una
referencia a la clase base …
2. llamamos al constructor copia para crear una nueva copia de esa
clase…
3. ¡Estamos llamando al constructor copia de la clase base para
copiar una clase derivada!
 Constructores virtuales
 Los constructores no pueden ser virtuales
 Si un constructor llama a una función virtual, ésta será siempre
la de la clase base (la clase derivada aún no se ha creado)
 Para solucionar este inconveniente se suele crear una función
virtual "clonar" en la clase base que se superpondrá para cada
clase derivada
ESCUELA TÉCNICA SUPERIOR DE INGENIERÍA INFORMÁTICA
105
Polimorfismo
P R O
G
R A
M A C
I
Ó
N
 Ejemplo:
class Persona {
public:
Persona(char *n) { strcpy(nombre, n); }
Persona(const Persona &p);
virtual Persona* Clonar() { return new Persona(*this); }
protected:
char nombre[30];
};
class Empleado : public Persona {
public:
Empleado(char *n) : Persona(n) {}
Empleado(const Empleado &e);
virtual Persona* Clonar() { return new Empleado(*this); }
};
class Estudiante : public Persona {
public:
Estudiante(char *n) : Persona(n) {}
Estudiante(const Estudiante &e);
virtual Persona* Clonar() { return new Estudiante(*this); }
};
ESCUELA TÉCNICA SUPERIOR DE INGENIERÍA INFORMÁTICA
106
Clases abstractas
P R O
G
R A
M A C
I
Ó
N
 Funciones virtuales puras
 Una función virtual pura es aquella que no necesita ser
definida
 El modo de declarar una función virtual pura es
asignándole el valor cero
class Persona {
public:
Persona(char *n) { strcpy(nombre, n); }
virtual void Mostrar() = 0;
protected:
char nombre[30];
};
ESCUELA TÉCNICA SUPERIOR DE INGENIERÍA INFORMÁTICA
107
Clases abstractas
P R O
G
R A
M A C
I
Ó
N
 Clase abstracta
 Una clase abstracta es aquella que posee al menos una
función virtual pura
 No es posible crear objetos de una clase abstracta, estas
clases sólo se usan como clases base para la declaración
 Las funciones virtuales puras serán aquellas que siempre
se definirán en las clases derivadas, de modo que no se
necesita implementación base
 Siempre hay que definir todas las funciones virtuales de
una clase abstracta en sus clases derivadas, no hacerlo así
implica que la nueva clase derivada será también abstracta
ESCUELA TÉCNICA SUPERIOR DE INGENIERÍA INFORMÁTICA
108
Clases abstractas
P R O
G
R A
M A C
I
Ó
N
 Ejemplo:
class Persona {
public:
Persona(char *n) { strcpy(nombre, n); }
virtual void Mostrar() = 0;
protected:
char nombre[30];
};
class Empleado : public Persona {
public:
Empleado(char *n, int s) : Persona(n), salario(s) {}
void Mostrar() { cout << "Empleado: " << nombre << ", Salario: " <<
salario << endl; }
protected:
int salario;
};
Persona *Jose = new Persona(“Jose”); // ERROR
Persona *Pepito = new Empleado(“Pepito", 1000);
ESCUELA TÉCNICA SUPERIOR DE INGENIERÍA INFORMÁTICA
109
Interfaces
P R O
G
R A
M A C
I
Ó
N
 Las interfaces surgen como una evolución de la POO
 Programación orientada a componentes
 ante la necesidad de reutilizar y agrupar las distintas
funcionalidades de un objeto en subconjuntos mas manejables
 Definen un cierto comportamiento o cualidades
 En términos de C++ es una clase abstracta con métodos
virtuales puros
 La derivación múltiple nos permitirá luego agrupar varias
de esas funcionalidades dentro de una clase
 nuestro objeto ira cobrando forma a partir de la herencia de
distintas interfaces o cualidades
ESCUELA TÉCNICA SUPERIOR DE INGENIERÍA INFORMÁTICA
110
Interfaces
P R O
G
R A
M A C
I
Ó
N
 Ejemplo:
/* Interface para objetos dibujables */
class IDrawable {
public:
Virtual bool IsVisible()=0;
virtual void Draw()=0;
};
/* Interface para objetos actualizables */
class IUpdateable {
public:
virtual void Update(float dt)=0;
};
Class Actor : public IUpdateable, public IDrawable {
Public:
bool IsVisible() { return true }
void Draw() { ... }
void Update (float dt) { ... }
}
ESCUELA TÉCNICA SUPERIOR DE INGENIERÍA INFORMÁTICA
111
Derivación múltiple
P R O
G
R A
M A C
I
Ó
N
 C++ permite crear clases derivadas a partir de varias
clases base
 Los objetos heredarán los datos y funciones de todas las
clases base
 Al construir el nuevo objeto, si es necesario debemos
llamar a los constructores de todas las clases base
ESCUELA TÉCNICA SUPERIOR DE INGENIERÍA INFORMÁTICA
112
Derivación múltiple
P R O
G
R A
M A C
I
Ó
N
 Ejemplo:
class ClaseA {
public:
ClaseA(int va = 10) : valorA(va) {}
int LeerValor() const { return valorA; }
protected:
int valorA;
};
class ClaseB {
Public:
ClaseB(int vb = 20) : valorB(vb) {}
int LeerValor() const { return valorB; }
protected:
int valorB;
};
class ClaseC : public ClaseA, public ClaseB {
public:
ClaseC(int va, int vb) : ClaseA(va), ClaseB(vb) {};
int LeerValorA() const { return ClaseA::LeerValor(); }
int LeerValorB() const { return ClaseB::LeerValor(); }
};
ESCUELA TÉCNICA SUPERIOR DE INGENIERÍA INFORMÁTICA
113
Derivación múltiple
P R O
G
R A
M A C
I
Ó
N
 Problema: Supongamos que tenemos una estructura de
clases
 La ClaseD heredará dos veces los datos y funciones de la
ClaseA, con la consiguiente ambigüedad a la hora de
acceder a datos o funciones heredadas de ClaseA
ESCUELA TÉCNICA SUPERIOR DE INGENIERÍA INFORMÁTICA
114
Derivación múltiple
P R O
G
R A
M A C
I
Ó
N
 Para solucionar esto se usan las clases virtuales
class ClaseB : virtual public ClaseA {};
class ClaseC : virtual public ClaseA {};
class ClaseD : public ClaseB, public ClaseC {};
 Desde el punto de vista de la ClaseB o ClaseC, no hay
ninguna diferencia entre ésta declaración y la que
hemos usado hasta ahora
 Sin embargo, ahora la
ClaseD sólo heredará una
vez la ClaseA
ESCUELA TÉCNICA SUPERIOR DE INGENIERÍA INFORMÁTICA
115
P R O
G
R A
M A C
I
Ó
N
Example 08 –Shapes
Jugando con la herencia y polimorfismo
ESCUELA TÉCNICA SUPERIOR DE INGENIERÍA INFORMÁTICA
116
Plantillas
P R O
G
R A
M A C
I
Ó
N
class TablaInt {
public:
TablaInt(int nElem);
~TablaInt();
int& operator[](int indice) { return pInt[indice]; }
...
private:
int *pInt;
int nElementos;
};
// Definición:
TablaInt::TablaInt(int nElem) : nElementos(nElem) {
pInt = new int[nElementos];
}
TablaInt::~TablaInt() {
delete[] pInt;
}
ESCUELA TÉCNICA SUPERIOR DE INGENIERÍA INFORMÁTICA
117
Plantillas
P R O
G
R A
M A C
I
Ó
N
 Según va aumentando la complejidad de nuestros
programas descubrimos que tenemos que repetir
una y otra vez las mismas estructuras
 A menudo tendremos que implementar arrays dinámicos
para diferentes tipos de objetos, o listas dinámicas, pilas,
colas, árboles, etc.
 El código es similar siempre, pero estamos obligados a
rescribir ciertas funciones que dependen del tipo o de la
clase del objeto que se almacena
 Las plantillas (templates) nos permiten parametrizar
estas clases para adaptarlas a cualquier tipo de dato
ESCUELA TÉCNICA SUPERIOR DE INGENIERÍA INFORMÁTICA
118
Plantillas
P R O
G
R A
M A C
I
Ó
N
 Ejemplo: plantillas de clases
template <class T>
class Tabla {
public:
Tabla(int nElem);
~Tabla();
T& operator[](int indice) { return pT[indice]; }
private:
T *pT;
int nElementos;
};
// Definición:
template <class T>
Tabla<T>::Tabla(int nElem) : nElementos(nElem) {
pT = new T[nElementos];
}
template <class T>
Tabla<T>::~Tabla() {
delete[] pT;
}
ESCUELA TÉCNICA SUPERIOR DE INGENIERÍA INFORMÁTICA
119
Plantillas
P R O
G
R A
M A C
I
Ó
N
 Ya sólo nos queda saber cómo declarar tablas del
tipo que queramos
Tabla<int> tablaInt(32); // Tabla de 32 enteros
Tabla<float> tablaFloat(12); // Tabla de 12 floats
Tabla<bool> tablaBool(10); // Tabla de 10 bools
ESCUELA TÉCNICA SUPERIOR DE INGENIERÍA INFORMÁTICA
120
Plantillas
P R O
G
R A
M A C
I
Ó
N
 Ejemplo: plantillas de funciones
template <class T>
T max(T x, T y) {
return (x > y) ? x : y;
};
 De esta forma tendremos definida la función max para
cualquier tipo de dato que tenga implementado
correctamente el operador “mayor que”
ESCUELA TÉCNICA SUPERIOR DE INGENIERÍA INFORMÁTICA
121
Plantillas
P R O
G
R A
M A C
I
Ó
N
 Es posible crear funciones que admitan parámetros
que sean una plantilla
 Hay dos modos de pasar las plantillas:
 se puede pasar una instancia determinada de la plantilla
 la plantilla genérica
ESCUELA TÉCNICA SUPERIOR DE INGENIERÍA INFORMÁTICA
122
Plantillas
P R O
G
R A
M A C
I
Ó
N
 Ejemplo: paso de una instancia determinada
void Incrementa(Tabla<int> &t);
...
void Incrementa(Tabla<int> &t) {
for(int i = 0; i < t.NElementos(); i++)
t[i]++;
}
Tabla<int> TablaInt(5);
Tabla<char> TablaChar(20);
Incrementa(TablaInt);
Incrementa(TablaChar); // ERROR
ESCUELA TÉCNICA SUPERIOR DE INGENIERÍA INFORMÁTICA
123
Plantillas
P R O
G
R A
M A C
I
Ó
N
 Ejemplo: paso de la plantilla genérica
template<class T>
void Mostrar(Tabla<T> &t);
...
template<class T>
void Mostrar(Tabla<T> &t) { // (4)
for(int i = 0; i < t.NElementos(); i++)
cout << t[i] << endl;
}
Tabla<int> TablaInt(5);
Tabla<char> TablaChar(20);
Mostrar(TablaInt);
Mostrar(TablaCadena);
ESCUELA TÉCNICA SUPERIOR DE INGENIERÍA INFORMÁTICA
124
Plantillas
P R O
G
R A
M A C
I
Ó
N
 Amigos de plantillas
template <class T>
class Tabla {
...
friend void Mostrar<>(Tabla<T>&);
...
};
template<class T>
class Tabla {
...
friend void Mostrar<>(Tabla<int>&);
...
};
ESCUELA TÉCNICA SUPERIOR DE INGENIERÍA INFORMÁTICA
125
Librería estándar de C++
P R O
G
R A
M A C
I
Ó
N
 El ANSI de C++ define ciertas librerías de plantillas
conocidas como STL (Standard Template Library)
 Contiene muchas definiciones de plantillas para crear
contenedores como listas, colas, pilas, árboles, tablas
HASH, mapas, etc.
 Además proporciona algoritmos que permiten manipular
fácilmente estos contenedores
 La STL introduce igualmente el concepto de iterador que
permite recorrer fácilmente un contenedor sin tener en
cuenta la manera en que ha sido implementado
ESCUELA TÉCNICA SUPERIOR DE INGENIERÍA INFORMÁTICA
126
P R O
G
R A
M A C
I
Ó
N
Example 09 - Plantilla de una pila
ESCUELA TÉCNICA SUPERIOR DE INGENIERÍA INFORMÁTICA
127
Excepciones
P R O
G
R A
M A C
I
Ó
N
 C++ proporciona un mecanismo más potente para
detectar errores de ejecución: las excepciones
 Si uno de esos errores se produce y no
implementamos el manejo de excepciones, el
programa sencillamente terminará abruptamente
 Para ello disponemos de tres palabras reservadas
extra: try, catch y throw
ESCUELA TÉCNICA SUPERIOR DE INGENIERÍA INFORMÁTICA
128
Excepciones
P R O
G
R A
M A C
I
Ó
N
 Ejemplo: manejo de excepciones
#include <iostream>
using namespace std;
int main() {
int *x;
int y = 100000000;
try {
x = new int[y];
x[0] = 10;
cout << "Puntero: " << (void *) x << endl;
delete[] x;
}
catch(std::bad_alloc&) {
cout << "Memoria insuficiente" << endl;
}
cin.get();
return 0;
}
ESCUELA TÉCNICA SUPERIOR DE INGENIERÍA INFORMÁTICA
129
Excepciones
P R O
G
R A
M A C
I
Ó
N
 Manejo de excepciones
 La manipulación de excepciones consiste en transferir la
ejecución del programa desde el punto donde se produce
la excepción a un manipulador que coincida con el motivo
de la excepción
 Un manipulador consiste en un bloque "try", donde se
incluye el código que puede producir la excepción
 A continuación encontraremos uno o varios bloques
"catch", y entre paréntesis una referencia o un objeto.
Estos bloques contienen el código necesario para tratar
una excepción de un tipo concreto
 En el caso del operador "new", si se produce una excepción,
se hace un "throw" de un objeto de la clase "std::bad_alloc"
ESCUELA TÉCNICA SUPERIOR DE INGENIERÍA INFORMÁTICA
130
Excepciones
P R O
G
R A
M A C
I
Ó
N
 Captura de excepciones
 Una excepción se puede producir por un "throw" que se
encuentre dentro del bloque "try" asociado, o en una de
las funciones llamadas desde él
 Cuando se produce una excepción se busca un
manipulador apropiado en el rango del "try" actual
 Si no se encuentra se retrocede al anterior, de modo
recursivo, hasta encontrarlo
 Cuando se encuentra se destruyen todos los objetos
locales en todos los niveles por los que hemos pasado
ESCUELA TÉCNICA SUPERIOR DE INGENIERÍA INFORMÁTICA
131
Excepciones
P R O
G
R A
M A C
I
Ó
N
 Ejemplo: propagación de excepciones
int main() {
try {
try {
try {
throw 'x'; // valor de tipo char
}
catch(int i) {}
catch(float k) {}
}
catch(unsigned int x) {}
}
catch(char c) {
cout << "El valor de c es: " << c << endl;
}
cin.get();
return 0;
}
ESCUELA TÉCNICA SUPERIOR DE INGENIERÍA INFORMÁTICA
132
Excepciones
P R O
G
R A
M A C
I
Ó
N
 Si no se encontrase ningún "catch" adecuado, se
abandona el programa, del mismo modo que si se
produce una excepción y no hemos hecho ningún
tipo de manipulación de excepciones
 Para evitar eso existe un "catch" general, que captura
cualquier "throw" para el que no exista un "catch"
catch(...) {
cout << "Excepción imprevista" << endl;
}
ESCUELA TÉCNICA SUPERIOR DE INGENIERÍA INFORMÁTICA
133
Excepciones
P R O
G
R A
M A C
I
Ó
N
 La clase exception
 Existe una clase base "exception" de la que podemos
heredar nuestras propias clases derivadas para pasar
objetos a los manipuladores
 Aplicando polimorfismo necesitamos un único "catch" para
procesar todas las posibles excepciones
class exception {
public:
exception() throw() { }
virtual ~exception() throw();
virtual const char* what() const throw();
};
ESCUELA TÉCNICA SUPERIOR DE INGENIERÍA INFORMÁTICA
134
Excepciones
P R O
G
R A
M A C
I
Ó
N
 Ejemplo: custom exception
class customException : public exception {
public:
customException(int mot) : exception(), motivo(mot) {}
const char* what() const throw();
private:
int motivo;
};
const char* customException::what() const throw() {
switch(motivo) {
case 1:
return "Fichero de origen no existe";
case 2:
return "No es posible abrir el fichero de salida";
}
return "Error inesperado";
}
ESCUELA TÉCNICA SUPERIOR DE INGENIERÍA INFORMÁTICA
135
Excepciones
P R O
G
R A
M A C
I
Ó
N
 Orden en la captura de excepciones
 Cuando se derivan clases desde la clase base "exception"
hay que tener cuidado en el orden en que las capturamos
 Debido que se aplica polimorfismo, cualquier objeto de la
jerarquía se ajustará al catch que tenga por argumento un
objeto o referencia de la clase base
ESCUELA TÉCNICA SUPERIOR DE INGENIERÍA INFORMÁTICA
136
Excepciones
P R O
G
R A
M A C
I
Ó
N
 Ejemplo: orden en captura excepciones
class Excep2 : public exception {}
class Excep3 :public Excep2 {}
...
try {
// Nuestro código
}
catch(Excep2&) {
// tratamiento
}
catch(Excep3&) {
// tratamiento
}
catch(exception&) {
// tratamiento
}
catch(...) {
// tratamiento
}
ESCUELA TÉCNICA SUPERIOR DE INGENIERÍA INFORMÁTICA
137
Excepciones
P R O
G
R A
M A C
I
Ó
N
 Especificaciones de excepciones
 Se puede añadir una especificación de las posibles
excepciones que puede producir una función
 De este modo indicamos que la función sólo puede hacer
un "throw" de uno de los tipos especificados en la lista
 El compilador no verifica si realmente es así, sólo se
verifica durante la ejecución, de modo que si se produce
una excepción no permitida, el programa termina
int Compara(int, int) throw();
int CrearArray(int) throw(std::bad_alloc);
int MiFuncion(char *) throw(std::bad_alloc, ExDivCero);
ESCUELA TÉCNICA SUPERIOR DE INGENIERÍA INFORMÁTICA
138
Excepciones
P R O
G
R A
M A C
I
Ó
N
 Excepciones en destructores
 Está desaconsejado que los destructores puedan producir
excepciones
 Los destructores pueden ser invocados automáticamente
cuando se procesa una excepción, y si durante ese proceso
se produce de nuevo una excepción, el programa
terminará inmediatamente
 La mejor solución es procesar las excepciones dentro del
destructor si es necesario
ESCUELA TÉCNICA SUPERIOR DE INGENIERÍA INFORMÁTICA
139
Excepciones
P R O
G
R A
M A C
I
Ó
N
 Ejemplo: excepciones en destructores
Miclase::~MiClase() throw () {
try {
// Necesitamos copiar un fichero cuando se
// destruya un objeto de esta clase, pero
// CopiaFichero puede generar una excepción
CopiaFichero("actual.log", "viejo.log");
}
catch(CopiaEx&) {
cout << "No se pudo copiar el fichero 'actual.log‘” <<
endl;
}
}
ESCUELA TÉCNICA SUPERIOR DE INGENIERÍA INFORMÁTICA
140
Excepciones
P R O
G
R A
M A C
I
Ó
N
 Relanzar una excepción
 Podemos lanzar una excepción a través de los siguientes
niveles, aunque la hayamos capturado
 A eso se le llama relanzarla, y para ello se usa "throw;", sin
argumentos
ESCUELA TÉCNICA SUPERIOR DE INGENIERÍA INFORMÁTICA
141
Excepciones
P R O
G
R A
M A C
I
Ó
N
 Ejemplo: relanzar una excepción
try {
// Programa
Programa();
}
catch(int x) {
cout << "Excepción relanzada capturada." << endl;
cout << "error: " << x << endl;
}
void Programa() {
try {
// Operaciones...
throw 10;
}
catch(int x) {
// Relanzar, no nos interesa manejar aquí
throw;
}
}
ESCUELA TÉCNICA SUPERIOR DE INGENIERÍA INFORMÁTICA
142
P R O
G
R A
M A C
I
Ó
N
Operadores de cambio de tipo en C++
ESCUELA TÉCNICA SUPERIOR DE INGENIERÍA INFORMÁTICA
143
Castings en C++
P R O
G
R A
M A C
I
Ó
N
 Hasta ahora hemos usado sólo el casting que existe en C,
pero su uso está desaconsejado
 Se recomienda usar uno de los nuevos operadores de
C++ diseñados para realizar esta tarea
 C++ dispone de cuatro operadores para realizar castings:




Operador static_cast<>
Operador const_cast<>
Operador reinterpret_cast<>
Operador dynamic_cast<>
ESCUELA TÉCNICA SUPERIOR DE INGENIERÍA INFORMÁTICA
144
Castings en C++
P R O
G
R A
M A C
I
Ó
N
 Operador static_cast<>
 Este operador se usa para realizar conversiones de tipo
que de otro modo haría el compilador automáticamente
 por ejemplo, convertir un puntero a un objeto de una clase
derivada a un puntero a una clase base pública
 Otro ejemplo, en lugar de usar el operador de conversión
de forma implícita, podemos usarlo mediante el operador
static_cast
 Este operador se usa con objeto de aclarar el código
pBase = static_cast<Base *> (pDerivada);
Tiempo Ahora(12,24);
int minutos = static_cast<int> (Ahora);
ESCUELA TÉCNICA SUPERIOR DE INGENIERÍA INFORMÁTICA
145
Castings en C++
P R O
G
R A
M A C
I
Ó
N
 Operador const_cast<>
 Se usa para eliminar o añadir los modificadores const y
volatile de una expresión
 La conversión tiene que ser del mismo tipo, salvo por los
modificadores const o volatile que tengan que aparecer o
desaparecer
const int x = 10;
int *x_var;
x_var = const_cast<int*> (&x); // Válido
// x_var = &x; // Ilegal, el compilador da error
*x_var = 14; // Indefinido
ESCUELA TÉCNICA SUPERIOR DE INGENIERÍA INFORMÁTICA
146
Castings en C++
P R O
G
R A
M A C
I
Ó
N
 Operador reinterpret_cast<>
 Se usa para hacer cambios de tipo a nivel de bits, es decir,
el valor de la expresión a convertir se interpreta como si
fuese un objeto del tipo deseado
 Este tipo de conversión es peligrosa
struct tipoRegistro {
char nombre[32];
int edad;
float altura;
};
ifstream fentrada("prueba.dat", ios::in | ios::binary);
fentrada.read(reinterpret_cast<char *> &pepe2, sizeof(tipoRegistro));
fentrada.close();
ESCUELA TÉCNICA SUPERIOR DE INGENIERÍA INFORMÁTICA
147
Castings en C++
P R O
G
R A
M A C
I
Ó
N
 Operador dynamic_cast<>
 Este operador sólo puede usarse con objetos polimórficos,
cualquier intento de aplicarlo a objetos de tipos
fundamentales o agregados o de clases no polimórficas
dará como resultado un error
 Lo que el programa intentará hacer, durante la ejecución,
es obtener un puntero o una referencia a un objeto de
cierta una base en forma de clase derivada
 pero puede que se consiga, o puede que no
ESCUELA TÉCNICA SUPERIOR DE INGENIERÍA INFORMÁTICA
148
Castings en C++
P R O
G
R A
M A C
I
Ó
N
 Operador dynamic_cast<>
 Con punteros:
void VerSueldo(Persona *p) {
if(Empleado *pEmp = dynamic_cast<Empleado *> (p))
pEmp->VerSueldo();
else
cout << "No tiene salario." << endl;
}
ESCUELA TÉCNICA SUPERIOR DE INGENIERÍA INFORMÁTICA
149
Castings en C++
P R O
G
R A
M A C
I
Ó
N
 Operador dynamic_cast<>
 Con referencias:
void VerSueldo(Persona &p) {
Empleado& rEmp = dynamic_cast<Empleado &> p;
...
}
 Al aplicar el operador con referencias hay que tener más
cuidado, ¿Qué pasará si el casting falla?
ESCUELA TÉCNICA SUPERIOR DE INGENIERÍA INFORMÁTICA
150
P R O
G
R A
M A C
I
Ó
N
Ficheros en C++
ESCUELA TÉCNICA SUPERIOR DE INGENIERÍA INFORMÁTICA
151
Ficheros en C++
P R O
G
R A
M A C
I
Ó
N
 Usar streams facilita mucho el acceso a ficheros en
disco
 veremos que una vez que creemos un stream para
un fichero, podremos trabajar con él igual que lo
hacemos con cin o cout
 Mediante las clases ofstream, ifstream y fstream
tendremos acceso a gran cantidad de funciones que
nos van a facilitar la tarea
ESCUELA TÉCNICA SUPERIOR DE INGENIERÍA INFORMÁTICA
152
Ficheros en C++
P R O
G
R A
M A C
I
Ó
N
#include <iostream>
#include <fstream>
using namespace std;
int main()
{
char cadena[128];
// Crea un fichero de salida
ofstream fs("nombre.txt");
fs << "Hola, mundo" << endl;
fs.close();
// Abre un fichero de entrada
ifstream fe("nombre.txt");
// Leeremos mediante getline, si lo hiciéramos mediante el operador >>
sólo leeríamos parte de la cadena:
fe.getline(cadena, 128);
cout << cadena << endl;
return 0;
}
ESCUELA TÉCNICA SUPERIOR DE INGENIERÍA INFORMÁTICA
153
Ficheros en C++
P R O
G
R A
M A C
I
Ó
N
 Muchos sistemas operativos distinguen
ficheros de texto y ficheros binarios
entre
 En general, usaremos ficheros de texto para almacenar
información que pueda o deba ser manipulada con un
editor de texto
 Ficheros binarios para todo lo demás
 Un fichero binario permite almacenar estructuras completas,
en las que se mezclen datos de cadenas con datos numéricos
ESCUELA TÉCNICA SUPERIOR DE INGENIERÍA INFORMÁTICA
154
Ficheros en C++
P R O
G
R A
M A C
I
Ó
N
struct tipoRegistro {
char nombre[32];
int edad;
float altura;
};
int main() {
tipoRegistro pepe, pepe2;
ofstream fsalida("prueba.dat", ios::out | ios::binary);
fsalida.write(reinterpret_cast<char *> &pepe, sizeof(tipoRegistro));
fsalida.close();
ifstream fentrada("prueba.dat", ios::in | ios::binary);
fentrada.read(reinterpret_cast<char *> &pepe2, sizeof(tipoRegistro));
fentrada.close();
return 0;
}
ESCUELA TÉCNICA SUPERIOR DE INGENIERÍA INFORMÁTICA
155
Ficheros en C++
P R O
G
R A
M A C
I
Ó
N
 Ficheros de acceso aleatorio
 Otra característica importante de los ficheros es la
posibilidad de trabajar con ellos haciendo acceso aleatorio,
es decir, poder hacer lecturas o escrituras en cualquier
punto del fichero
 Para eso disponemos de las funciones seekp y seekg, que
permiten cambiar la posición del fichero en la que se hará
la siguiente escritura o lectura
ESCUELA TÉCNICA SUPERIOR DE INGENIERÍA INFORMÁTICA
156
Ficheros en C++
P R O
G
R A
M A C
I
Ó
N
char cad[20];
char mes[][20] = {"Enero", "Febrero", "Marzo", ...};
// Acceso aleatorio
for(i = 11; i >= 0; i--) {
fentrada.seekg(20 * i, ios::beg);
fentrada.read(cad, 20);
cout << cad << endl;
}
/* Calcular el número de elementos almacenados en un fichero: */
// ir al final del fichero
fentrada.seekg(0, ios::end);
// leer la posición actual
pos = fentrada.tellg();
// El número de registros es el tamaño en bytes dividido entre el tamaño del
registro
cout << “Número de registros: " << pos/20 << endl;
ESCUELA TÉCNICA SUPERIOR DE INGENIERÍA INFORMÁTICA
157
Ficheros en C++
P R O
G
R A
M A C
I
Ó
N
 Sobrecarga de operadores << y >>
 Una de las principales ventajas de trabajar con streams es
que nos permiten sobrecargar los operadores << y >> para
realizar salidas y entradas de nuestros propios tipos de
datos
ostream& operator<<(ostream &os, Registro& reg) {
os << "Nombre: " << reg.LeeNombre() <<"\nEdad: " <<
reg.LeeEdad() << "\nTelefono: " << reg.LeeTelefono();
return os;
}
ESCUELA TÉCNICA SUPERIOR DE INGENIERÍA INFORMÁTICA
158
Ficheros en C++
P R O
G
R A
M A C
I
Ó
N
Example 10 - Importación de modelos 3D
Lectura de ficheros de texto mediante streams
ESCUELA TÉCNICA SUPERIOR DE INGENIERÍA INFORMÁTICA
159
Libros recomendados
P R O
G
R A
M A C
I
Ó
N
ESCUELA TÉCNICA SUPERIOR DE INGENIERÍA INFORMÁTICA
160
P R O
G
R A
M A C
I
Ó
N
Curso 0: Programación orientada a
objetos (POO)
Iván Alduán
([email protected])
(despacho 143 Departamental II, Campus Móstoles)
ESCUELA TÉCNICA SUPERIOR DE INGENIERÍA INFORMÁTICA
161