Apuntes PROII parcial 2

Anuncio
APUNTES PROII 2º PARCIAL.
MEMORIA DINÁMICA.
Hay que distinguir entre:


Estática: memoria que se reserva en tiempo de compilación.
Dinámica: memoria que se reserva en tiempo de ejecución.
5 pasos:
1.
2.
3.
4.
5.
Declaración de un puntero en la zona de atributos.
Reservar con el operador new la memoria en el constructor.
Validar que tenemos espacio en la memoria en el constructor.
Utilizar esa zona de memoria en donde queramos.
Eliminar la reserva con el operador delete en el destructor.
Ejemplo:
int main() {
int num;
int * puntero;
//Paso 1.
cout << "Introduzca el num de elementos:"
cin num;
puntero = new (nothrow) int [num];
//nothrow devuelve un null si no se ha podido reservar esa memoria
//Paso 2.
if(puntero == null){
cerr << "Error de memoria dinámica";
exit (-1);
}
//Paso 3.
for ( int i = 0; i < num; i++ ) {
cout << "Introduzca el valor" << i << endl;
cin puntero[i]; // equivalente a *(puntero+i)
}
//Paso 4
delete [] puntero;
//Paso 5.
return 1;
}
SOBRECARGA DE OPERADORES.
1. FORMAS DE SOBRECARGAR.
- Usando funciones amigas.
- Usando funciones miembro.
Funciones friend: es la función externa a la clase que tiene acceso a la parte privada de
esta.
2. TIPOS DE OPERADORES.
Operadores unarios.
Ej.: a++;
Sobrecargar como función friend:
friend valor_retorno operator++(tipo_operando a); //prototipo de la función
Sobrecargar como función miembro:
valor_retorno operator++();
Operadores binarios.
Ej.: a + b;
Sobrecargar como función friend:
friend valor_retorno+(tipo1_operador a, tipo2_operador b); //prototipo de la función
Sobrecargar como función miembro:
valor_retorno operator+(tipo_operator b);
Ejemplo:
Como función miembro:
Complejo a(5.3, 2);
Complejo b;
a = a + b;
Dentro de la clase Complejo:
Prototipo: Complejo operator+(Complejo b);
Su implementación:
Complejo Complejo::operator+(Complejo b){
Complejo toret;
toret.real = real + b.real;
toret.imaginaria = imaginaria + b.imaginaria;
return toret;
}
Como función amiga:
friend Complejo operator+(Complejo a, Complejo b); //Prototipo dentro de la clase
Complejo operator+(Complejo a, Complejo b) { //Implementación de la función friend
Complejo toret;
toret.real = a.real + b.real;
toret.imaginaria = a.imaginaria + b.imaginaria;
return toret;
}
Sobrecarga de operadores <<, >>.
Siempre se implementan como función friend:
Sobrecarga de << (operador de inserción):


Como valor de retorno siempre ostream por referencia.
El primer argumento es un flujo de salida y el segundo lo que queremos sacar por
pantalla.
Prototipo para la clase catalogo:
friend ostream & operator<<(ostream & o, Catalogo c);
Sobrecarga de >>(operadir de extracción):

Como valor de retorno istream por referencia
Prototipo para la clase catálogo:
friend istream & operator>>(istream & i, Catalogo & c);
En el código de la sobrecarga, primero se implementa el destructor y luego el código del
constructor de copia.
GESTIÓN DE EXCEPCIONES.
Hay dos tipos de excepciones: las que genera el sistema y las que generamos nosotros.
Sintaxis:
try { //aquí irán todas las sentencias en las que se puede generar una excepción+
if(.....)
{
throw nombre excepción //lanza una excepción
}catch(tipo 1 arg 1){ //puede o no tener argumentos. Es el manejador de excepciones.
}catch(tipo 2 arg 2){ // un try puede tener asociados varios catch
}catch(...){ //catch universal, maneja cualquier tipo de excepción
}
Ejemplo:
try {
if ( temperatura < 0 )
throw "Mucho frío";
else if ( temperatura > 0 && temperatura < 30 )
throw temperatura;
else throw "Mucho calor";
}catch ( string c ) {
cout << c;
}catch ( int c ) {
cout << c;
}catch ( ... ) {
...
}
Se suele poner un único manejador en el main que controle todas las excepciones del
programa.
#include <exception> //La clase exception tiene una funcion definida what(); que visualiza la
pila, hace un volcado de pila.
bad_alloc
int * puntero;
try{
puntero = new int [10];
}catch(const bad_alloc & e){
cerr << e.what() << endl;
}
Clase excepción:
class Excepcion1{
public:
Excepcion1(const string &d){
descripcion = d;
}
//suele tener 2 constructores
//aquí se le pasaría const char * descripcion
void visualizar(){
cerr << descripcion;
}
private:
string descripcion; o char * descripcion
};
HERENCIA Y COMPOSICIÓN.
Tipos de relaciones existentes entre clases.
Herencia = es_un
Composición = contiene_un
Se permiten 2 tipos de herencia.
1. Herencia simple.
Clase base o clase padre + una o mós clases derivadas o hijo.
Una clase únicamente puede heredar de una clase.
Ejemplo:
class Persona {
private: int edad;
};
class Becario {
private: float beca;
};
Becario heredará de persona.
SINTAXIS:
class Derivada: modificador clase_Base {
public:
Derivada(arg Base + arg derivada): Base(nombre arg Base) {
.....
}
//Lo que haga falta
private:
//Lo que haga falta.
}
Ejemplo:
class Persona {
public:
Persona(){edad=0}
Persona(int e){edad=e}
private:
int edad;
};
class Becario:public Persona {
public:
Becario(){beca = 0.0}
Becario(int e, float b):Persona(e) {
beca = b;
}
private:
float beca;
}
MODIFICADOR
public
protected
private
CLASE BASE
public
protected
private
public
protected
private
public
protected
private
CLASE DERIVADA
public
protected
INACCESIBLE
protected
protected
INACCESIBLE
private
private
INACCESIBLE
2. Herencia múltiple.
Varias clases padre.
Sintaxis:
class Derivada:public Base1, public Base2 {
public:
Derivada(tipo nombre):Base1(nombre_atributo),Base2(nombre_atributo) {
....
}
};
En el archivo .h pondríamos:
class Derivada:public Base1, public Base2{
public:
Derivada(tipo nombre);
};
En herencia múltiple no podemos separar en .h y .ccp por que se producen errores.
LIGADURA DINAMICA.
Hay 2 tipos de funciones virtuales: puras o normales.

A las puras le asignamos la dirección 0 o null, sin código.

En las normales se da la opción en la clase derivada de implementar o no. Si en la clase
derivada se implementa se llama a esa, si no se llamará a la de la clase base.
La clase en la que haya una función virtual se convierte en abstracta y su constructor se
convierte en virtual.
No podemos crear objetos de la clase base.
La ligadura dinámica retrasa hasta tiempo de ejecución el linkado de una función con su
código.
Pasos:
1. Crear un puntero que apunte a una clase base que contenga alguna función virtual.
2. Darle la dirección de un objeto de una clase derivada al puntero.
3. Acceder mediante -> a la función virtual.
Descargar