Tema2 programacion i_ib

15
Programación II 1 Tema 2. Programación Orientada a Objetos Programación II Programación II 2 Índice Introducción Declaración de una clase Encapsulación Representación gráfica de una clase Constructores y destructores Creación y eliminación dinámica de objetos Paso y retorno de objetos a funciones Otras características Operador asignación Operador this Atributos estáticos Métodos constantes Composición Bibliografía Ejemplos y ejercicios Programación II 3 Introducción Programación orientada a objetos: ¿Qué es? ¿Para qué sirve? ¿Por qué? ¿Cómo surgió? ¿Dónde debe usarse? ¿Cómo debe usarse? ..... La programación orientada a objetos ha surgido con motivo de una evolución en la forma de desarrollar proyectos software. No se trata de una nueva metodología, apareció en los años 60 con el lenguaje Simula-67. Muchos de los lenguajes actuales utilizan este paradigma. Programación II 4 Introducción II. Historia I. Las técnicas de programación han considerando distintas entidades a lo largo del tiempo, las cuales cada vez tienen un mayor nivel de abstracción. Parece muy lejano la programación en binario, pero solamente han transcurrido 50 años. Se pueden clasificar: Prehistoria de la programación (maquina) Programación estructurada Programación procedimental Programación Modular Los tipos abstractos de datos Programación orientada a objetos

Transcript of Tema2 programacion i_ib

Page 1: Tema2 programacion i_ib

Programación II 1

Tema 2. Programación Orientada a Objetos

Programación II

Programación II 2

Índice● Introducción● Declaración de una clase● Encapsulación● Representación gráfica de una clase● Constructores y destructores● Creación y eliminación dinámica de objetos● Paso y retorno de objetos a funciones● Otras características

– Operador asignación– Operador this– Atributos estáticos– Métodos constantes

● Composición● Bibliografía● Ejemplos y ejercicios

Programación II 3

Introducción● Programación orientada a objetos:

– ¿Qué es?– ¿Para qué sirve?– ¿Por qué?– ¿Cómo surgió?– ¿Dónde debe usarse?– ¿Cómo debe usarse?– .....

● La programación orientada a objetos ha surgido con motivo de una evolución en la forma de desarrollar proyectos software.

● No se trata de una nueva metodología, apareció en los años 60 con el lenguaje Simula-67. Muchos de los lenguajes actuales utilizan este paradigma.

Programación II 4

Introducción II. Historia I.● Las técnicas de programación han considerando distintas

entidades a lo largo del tiempo, las cuales cada vez tienen un mayor nivel de abstracción. Parece muy lejano la programación en binario, pero solamente han transcurrido 50 años.

● Se pueden clasificar:– Prehistoria de la programación (maquina)– Programación estructurada– Programación procedimental– Programación Modular– Los tipos abstractos de datos – Programación orientada a objetos

Page 2: Tema2 programacion i_ib

Programación II 5

Introducción III. Historia II● Programación Estructurada

– Introducción de una serie de estructuras de control básicas● Secuencia● Selección● Iteración

– De este modo se construyen programas más legibles y fáciles de mantener.

– Sin duda alguna supuso un cambio bastante importante, pero los problemas complejos son difíciles de mantener.

Programación II 6

Introducción III. Historia II● Programación Procedimental

– Se basa en la idea de descomponer los programas en funciones que resuelvan el problema.

– Una vez determinadas las funciones, para la solución del problema solamente se deben realizar llamadas a estas funciones.

– Se debe definir separadamente las estructuras de datos que manejan los programas.

– Inconvenientes:● Realizar una descomposición procedimental para resolver problemas

complejos es muy difícil.● Dificultad de reutilización

– Lenguajes procedimentales: C, Pascal, fortran, ....

Programación II 7

Introducción IV. Historia III.● Programación modular

– La idea es dividir el problema en módulos independientes qué representen una caja negra donde cada módulo resuelva una parte del problema.

– Dentro de cada uno de los módulos se incluyen los procedimientos y funciones que proporcionen la funcionalidad deseada de ese módulo.

– Con esta técnica el problema puede ser resueltos por distintas personas, donde cada una implementa sus módulos.

– Con esta programación aparecen otros conceptos:● Compilación separada● Interfaz de utilización de un módulo● Se puede dividir el problema en módulos más comprensibles

– Inconvenientes:● Realizar una descomposición procedimental para resolver problemas

complejos es muy difícil.● Dificultad de reutilización

Programación II 8

Introducción V. Historia IV● Tipos abstractos de datos

– El objetivo es definir cuales son las estructuras de datos y definir sus operaciones de manipulación.

– Se basa en la programación modular y el objetivo es conseguir la encapsulación del código y datos.

– El objetivo es que el acceso a los datos se produzca mediante las funciones aunque realmente no se consigue dicho objetivo.

– Algunos autores clasifican esta técnica como la antesala de la programación orientada a objetos.

– El principal inconveniente radica en que conceptos como herencia, polimorfismo no se pueden contemplar en esta técnica.

Page 3: Tema2 programacion i_ib

Programación II 9

Introducción VI. Historia V.● Programación orientada a objetos

– Metodología basada en la idea natural de la existencia de un mundo lleno de objetos. Todo es objeto software.

– El objetivo es identificar los objetos y definir sus comportamientos.– La solución al problema se consigue mediante una secuencia de

pasos de mensajes entre los objetos.– Ventajas:

● Favorece el diseño de sistemas software complejos.● Reusabilidad: Reutilización del código● Extensibilidad: Extensión del código● Reducir el coste de desarrollo y mantenimiento● Mejorar la productividad de los programadores● Sistemas más robustos y estables.

– Otros conceptos: herencia, polimorfismo, vinculación dinámica,....

Programación II 10

Introducción VII. Historia VI.● Nomenclatura usada:

Conceptos empleados en las Técnicas Orientadas a

Objetos

Técnicas Tradicionales C++

Métodos Procedimientos, funciones o subrutinas

Función miembro

Variables Instancia Datos Miembros

Objeto , instancia Variable Objeto

Mensajes Llamadas a procedimientos y funciones

Llamada a función

Clases Tipos Abstractos de Datos Clases

Herencia No existe técnica similar Derivación

Subclase No existe técnica similar Clase derivada

Llamadas bajo control del sistema

programa=sistema de objetos interactivos

Llamadas bajo el control del programador

programa=secuencia de instrucciones

Programación II 11

Declaración de una clase● Antes de crear un objeto deberemos establecer su plantilla o

formato -> Clase. Ej: Punto, vehículo, televisor, persona● Para cada clase se deben describir sus características y su

comportamiento.● Una clase es la especificación de un tipo de objeto que se

encuentra formado:– Sus características, tanto físicas como lógicas--> Atributos– Su comportamiento, operaciones que se pueden realizar en una clase

--> Métodos o funciones (Miembro en C++)● Debemos diferenciar claramente entre:

– Clase--> Plantilla de un objeto– Objeto --> Ejemplares o variables de una clase.

Programación II 12

Declaración de una clase IIclass Nombre_clase {

//atributos//Miembros

};Ejemplo. Clase Puntoclass Punto {

int _x, _y;void dibujar ();int leer_x();int leer_y();void dar_x(int x);void dar_y(int y);

};

Page 4: Tema2 programacion i_ib

Programación II 13

Declaración de una clase III● Implementación de las funciones miembros: Dos tipos:

– Funciones miembros insertadas. En la propia definición se realiza su implementación.

– Funciones miembros fuera de la clase. Se implementan fuera de la definición de la clase. Tipo Nom_Clase::Func_Miem(Parametros) {};

class Punto {

int _x, _y; //Atributos

void inicializar () { _x=0;_y=0;}; //Función miembro insertada

int leer_x() {return _x;} //Función miembro insertada

int leer_y() {return _y;} //Función miembro insertada

void dar_x(int x);

void dar_y(int y);

};

void Punto::dar_x (int x) { void Punto::dar_y (int y) {

this->_x=x; this->_y=y;

} }

Implementación de las funciones miembros externas a su definición

Programación II 14

Declaración de una clase IV● Cada variable que se declara de una clase se conoce como

objeto de una clase.● Todos los objetos de una misma clase tienen las mismas

características y miembros pero con diferentes valores. ● Declaración de un objeto:

Nombre_Clase obj1, obj2, ....objN;● Ejemplo: Queremos declarar 3 objetos puntos:

Punto punto_1, punto_2, punto_3;

Programación II 15

Declaración de una clase. Vusing namespace std;

int main() {

Punto p; //Declaramos un objeto de tipo punto

int m,n;

cout<<”Escribe la coordenada X:”<<endl;

cin >>m;

cout<<”Escribe la coordenada y:”<<endl;

cin >>n;

p.dar_x(m);

p.dar_y(n);

cout<<”La coordenada X es: ”<< p.leer_x()<<endl;

cout<<”La coordenada Y es: ”<< p.leer_y()<<endl;

return 0;

}

Programación II 16

Declaración de una clase VI● Los objetos se manipulan mediante el paso de mensajes. ● El funcionamiento de una aplicación OO se realiza mediante

el paso de mensajes entre las distintas instancias del mismo. ● De este modo:

– Los mensajes inician acciones– Los mensajes se envían a objetos– Un objeto recibe mensajes y ejecuta métodos: ocultación de

información

Page 5: Tema2 programacion i_ib

Programación II 17

Encapsulación I● Uno de los pilares básicos de la POO es la encapsulación de

los datos. El acceso a los datos de una clase deben realizarse de forma controlada, protegiéndolos de acceso no autorizados.

● De este modo, existe una ocultación de la información fuera de la clase.

● Los atributos deben estar ocultos --> Privado, aunque C++ permite declararlos público, nunca lo usaremos.

● Las funciones miembros permiten el acceso a los atributos --> Pública, aunque pueden existir funciones miembros privadas que son usadas por las públicas.

● De este modo se busca que el acceso a los datos sea controlado y sólo se puede realizar mediante las funciones miembros.

Programación II 18

Encapsulación II● La definición anterior se ve modificada:class Punto {

private:int _x, _y;

public:void dibujar();.....

};● Los modificadores de acceso son:

– Public: Su acceso se puede realizar desde fuera de la clase– Private: Su acceso esta limitado dentro de la clase. – Protected: Se verá posteriormente

● Ejemplo: Definir las siguientes clases: Vehículo, persona y círculo.

Programación II 19

Encapsulación III● A los elementos privados sólo se pueden acceder desde

dentro de la clase, mientras que a lo público se accede desde cualquier objeto.

● Los atributos de una clase son datos de tipos previamente definidos u objetos de otras clases.

● Dentro de la clase– Se puede acceder a los atributos– Se puede acceder a los métodos públicos y privados

● Desde un objeto– No se puede acceder a los atributos privados– No se puede acceder a las funciones miembros privadas– Sólo se puede acceder a las funciones miembros públicas– Se utiliza el paso de mensaje: objeto.mensaje

Programación II 20

Encapsulación IV. Ejemplo● Ejemplo Clase Persona.

class Persona {private:

char _nombre[30];char _nif[10];int _edad;

public:void inicializar (char *nombre, char * nif,int edad);void leer_nombre(char *nombre);void leer_nif(char *nif);void leer_edad(int edad);char * dar_nombre();char * dar_nif();int dar_edad();void mostrar();

};

Page 6: Tema2 programacion i_ib

Programación II 21

Encapsulación V● Convenios de denominación

– Los identificadores se escribirán en general en minúsculas, a excepción, en los casos que se indique, de ciertas letras.

– Las clases comenzarán por mayúscula: Clase, Punto, Circulo. – Los atributos comenzarán por subrayado: _x, _y. – Los métodos comenzarán por minúscula. Aquellos que sean

específico de un determinado atributo llevarán un guión: leer_x (), leer_y().

– Los objetos comenzarán por minúscula: objeto1, punto. – Los identificadores compuestos por varias palabras: la segunda y

siguientes palabras llevarán su primera letra en mayúscula: listaPuntos, vectorPuntos.

Programación II 22

Representación gráfica● Para representar gráficamente los elementos de los programas

OO y sus relaciones vamos a utilizar los diagramas UML que son usados dentro de la Ingeniería del Software.

● Según se vayan mostrando los distintos conceptos de OO se presentará su representación UML.

● Representación de una clase

● Se pueden omitir alguna de las secciones o dejarse en blanco

Nombre_ClaseAtributosMétodos

Punto

_x:int_y:int

Inicializar(x:int,y:int):voiddar_x:intdar_y:int

leer_x(x:int):voidleer_y(y:int):void

Programación II 23

Constructores y Destructores● Tal y como se ha podido comprobar la declaración de objetos

se realiza de la misma forma que para el resto de las variables.

● De forma que cuando se necesita, primero se crea la variable y posteriormente se destruye.

● Pero en la POO existe una peculiaridad. Cuando se crea un objeto se produce una llama de forma automática a un método especial denominado constructor.

● Y cuando se destruye se realiza otra llamada automática al destructor.

● Si nosotros no lo proporcionamos, el compilador generará unos por defecto, pero como veremos posteriormente esta situación no es realmente conveniente.

Programación II 24

Constructores y Destructores II● Constructor: Función miembro encargada de inicializar las

instancias de clase cuando estas son creadas.● Los constructores deben tener el mismo nombre que la clase y

nunca puede devolver ningún tipo de dato.● Los constructores deben definirse dentro de la sección pública,

pues sino, no se tendría acceso a los mismos.● Sintaxis:

class Nombre_Clase {nombre_clase::nombre_clase(parámetros); //Definición Constructor.....

};nombre_clase::nombre_clase(parámetros) { //Implementación

}

Page 7: Tema2 programacion i_ib

Programación II 25

Constructores y Destructores III● Ejemploclass Punto {

public:

Punto(); //Constructor. Definición......

};

Punto::Punto() { //Constructor. Implementación

cout << “Estoy en el constructor”<< endl;

_x=0; _y=0;

}

.....

int main() {

Punto p; //Se produce la llamada al constructor automáticamente

.....

}; Programación II 26

Constructores y Destructores IV● A veces es necesario poder inicializar los objetos de distintas

formas. Por ejemplo, disponer un constructor que los inicialice a un valor por defecto o un constructor que recibe por parámetros los valores de cada uno de los atributos. --> Sobrecarga de funciones.

● La sobrecarga de funciones nos permite definir funciones con el mismo nombre pero con distinta signatura (número y tipo de parámetros).

● Clasificación de los constructores– Constructor predeterminado: No tiene ningún argumento.– Constructor Parametrizado: Reciben por parámetro los valores

iniciales de los atributos de la clase. Se pueden definir varios constructores parametrizados para una clase.

Programación II 27

Constructores y Destructores VClass Punto {

Punto(); //Constructor por defecto

Punto(int a, int b); //Constructor parametrizado ***

Punto (int a); //Constructor parametrizado

.....

};

int main() {

Punto p; //Llamada constructor por defecto

Punto p1(5); //Llamada constructor parametrizado

Punto p2 = Punto(2,3); //Llamada constructor parametrizado

Punto p3[6]; //Vector de puntos. Constructor parametrizado para cada posición

};

***Cuidado: Si se hubiera usado int a=0, int b=0, daría problema de anbigüedad pues el compilador no sabría cual de los constructores tiene que usar (Entre el 1 y el 2). Si se quiere valores por defecto sobraría el último constructor.

Programación II 28

Constructores y Destructores VI

● En las clases debe existir un constructor por defecto, que no tenga argumentos, y este se invoca siempre que se crea un objeto (si no es con parámetros).

● Si no se proporciona uno, el compilador genera automáticamente un constructor por defecto.

● Este constructor funcionará correctamente siempre y cuando no tengamos un atributo dinámico dentro de la clase. En este caso se debe implementar un constructor por defecto, debido a que en éste se deberá realizar la reserva de memoria.

Page 8: Tema2 programacion i_ib

Programación II 29

Constructores y Destructores VII● Destructores: Función miembro encargada de “destruir”

toda la información asociada a una instancia de una clase, principalmente si se había reservado memoria.

● Igual que el constructor:– Es invocado automáticamente por el compilador– No tiene argumentos

● Importante: Sólo puede existir uno por clase● Sintaxis:

~Nombre_Clase();● Ejemplo:

~Punto();~Persona();

Programación II 30

Constructores y Destructores VIII● Constructor copia

– Existe otro constructor muy importante en la OO, el cual es utilizado cuando se crea un objeto a partir de otro.

– Igual que con el constructor por defecto, si no se proporciona uno el compilador genera uno.

– El constructor copia por defecto copia bit a bit los atributos de la instancia copiada.

– Este constructor funciona correctamente siempre y cuando no existan atributos que se accedan mediante punteros, pues si se copia bit a bit el atributo de los dos objetos apuntarían a la misma dirección.

● Ejemplo:Punto p(10,10); //Constructor parametrizado

Punto p2=p1; //Inicialización por copia. Se crea p2 a partir de p1

Punto p3(p2); //Constructor copia. Se crea p3 a partir de p2

Programación II 31

Constructores y Destructores IX● El constructor copia se utiliza:

– Cuando se crea un objeto a partir de otro (Casos anteriores)– Cuando a una función se le pasan objetos por valor.

void fx (Punto p) {......}– Cuando una función retorna un objeto como valor de retorno. Al terminar

la ejecución se crea una copia del objeto que se devuelve.Punto fx(....) {

Punto x;return x; }

● En estos casos, como se crea una copia del objeto bit a bit que sucede cuando termina el ámbito del primer o segundo objeto y se llama al destructor y por tanto se libera su memoria? Si los dos objetos apuntan a la misma dirección?

Programación II 32

Constructores y Destructores X

Persona p1;char * Nombre

Persona p2=p1

Persona p2;char * Nombre

Juan Persona p1;char * Nombre

Persona p2=p1

Persona p2;char * Nombre

Juan

Juan

Constructor Copia por defecto Constructor Copia

Page 9: Tema2 programacion i_ib

Programación II 33

Constructores y Destructores XI● Implementación del constructor copia de la clase PersonaPersona::Persona(const Persona& origen) {

nombre= new char[strlen(origen.mensaje)+1];

strcpy(nombre,origen.nombre);

}

Persona::Persona (char *nom) {

nombre=new char [strlen(nom)+1];

strcpy(nombre,nom);

}

Persona::~Persona() {

if (nombre) {

delete [] nombre;nombre=NULL;

}

}

Constructor copia

Liberación de la memoria

Reserva de memoria en el constructor

Programación II 34

Constructores y Destructores XII● Resumen:

Para cada clase que definamos siempre se crearán los siguientes objetos

– Constructor por defecto– Constructor copia – Constructor parametrizado (Opcional)– Operador asignación “=” (Se presentará posteriormente)– Destructor (Aunque en algunas ocasiones no realice ninguna

operación)

Programación II 35

Creación y eliminación dinámica de objetos ● Como cualquier otra variable, existen dos formas de crear un

objeto:– Estáticamente: Los objetos son creados y destruidos cuando ha

terminado su ámbito. El compilador controla su ciclo de vida.– Dinámicamente: El programador es el encargado de controlar su

creación y destrucción.● ¿Porque se necesita objetos dinámicos si con los estáticos

puedo trabajar bien?– Sólo se reserva memoria cuando se necesita– Se liberan los objetos cuando ya no se necesitan, mientras que del

otro mecanismo es el compilador quien los libera cuando termina su ámbito.

● Ejemplo: Para almacenar 100 puntos, existen dos opciones un vector de puntos (se reserva la memoria para 100 puntos) o mediante programación dinámica, donde según se necesita un punto se reserva memoria para él.

Programación II 36

Creación y eliminación dinámica de objetos II● Como para el resto de variables dinámicas en C++ se utilizan

los operadores new y delete.● Un objeto dinámico como cualquier variable dinámica tiene

el siguiente ciclo de vida:– Definir el puntero a un objeto

Punto * p;– Reservar la memoria e inicializar el objeto (Constructor)

p= new Punto(); – Utilizar el objeto

p->leer_x();– Liberar la memoria reservada por el objeto

delete (p);

p

p

Punto

X:inty:int

Inicializar(x:int,y:int):voidDarX:intDarY:int

LeerX(x:int):voidLeerY(y:int):void

Page 10: Tema2 programacion i_ib

Programación II 37

Creación y eliminación dinámica de objetos III● Vector de objetos. Dos formas:

– Estática: Punto p[10]; – Dinámica. Utilizando los operadores new y delete. Dos soluciones.

● Primera– Punto * p[2];– p[0]= new Punto(4,4); //Cualquier otro constructor– p[0]->leer_x();– cout<<"La coordenada X es: "<< p[0]->leer_x()<<endl;– cout<<"La coordenada Y es: "<< p[0]->leer_y()<<endl;– delete p[0];

● Segunda– Punto * p1;– p1=new Punto[2]; //Se esta llamando al constructor por defecto– p1[0].leer_x();– cout<<"La coordenada X es: "<< p1[0].leer_x()<<endl;– cout<<"La coordenada Y es: "<< p1[0].leer_y()<<endl;– delete []p1; Programación II 38

Creación y Eliminación dinámica de objetos IV

● Precauciones a tener con los punteros:– Siempre reservar memoria cuando se vaya a usar. Si se intenta

acceder al contenido apuntado por un puntero sin haber reservado memoria puede ser catastrófico.

– Intentar liberar dos veces un puntero

– Intentar liberar un puntero para el cual no se ha liberado memoria

– No liberar el espacio reservado

Programación II 39

Paso y retorno de objetos a funciones● Los objetos como cualquier otra variable se pueden pasar a

las funciones. Existen principalmente dos formas:– Por valor: El compilador genera una copia de la variable y es

utilizada en la función. – Por referencia: No se le pasa la variable sino una referencia de la

misma (más eficiente y permite modificar el contenido). Dos formas:● Como puntero (Heredado de C)● Como referencia (C++)

Ejemplo (int x, int *y, int &z)● Los objetos pueden ser pasados mediante estos tres métodos.

A continuación se exponen las ventajas e inconvenientes de cada uno de ellos.

Programación II 40

Paso y retorno de objetos a funciones II● Paso de objetos por valor:

– Igual que con las variables se produce una copia del objeto– Importante: Esto implica una llamada al constructor copia y una

llamada al destructor cuando finaliza su ámbito. – Problemas:

● Si no tenemos definido el constructor copia y se ejecuta el por defecto, se tienen problemas con atributos a punteros.

● Además parece poco eficiente pues se tiene que crear un objeto y destruirlo.

– Solución:● Usar paso por referencias constantes para pasar objetos por valor.

Page 11: Tema2 programacion i_ib

Programación II 41

Paso y retorno de objetos a funciones III● Paso por referencia (retorno por argumento)

– Con este método no se produce una copia del objeto en su invocación sino que se pasa una referencia del objeto. Ventajas:

● Eficiencia● Permite la modificación del objeto

– Inconveniente:● En ocasiones nos puede interesar solo tener acceso de lectura al objeto y

no de modificación. --> Paso de referencia constanteclass Punto {

......

Punto(const Punto &P); /*Constructor copia. Utiliza la palabra reservada const para que no se pueda modificar el objeto P. Paso por referencia constante. Si se intenta cambiar, el compilador da un fallo de compilación.*/

void Sumar_Punto (Punto& p); /*El objeto p puede modificarse dentro de la función.*/

}Programación II 42

Paso y retorno de objetos a funciones IV● Funciones que retornan objetos. Dos mecanismos:

– Por valor. – Por referencia (Puntero y referencias).

● En ambos casos, se deben tener ciertas precauciones y asegurarse de:

– Tener un constructor copia– Tener un operador asignación– Nunca devolver un objeto local creado en la función miembro:

● Se recomienda devolver un objeto por argumento, pues muchos de los problemas originados mediante “return” se resuelven.

Programación II 43

Paso y retorno de objetos a funciones V● Ejemplo:Punto * Punto::suma(Punto *p) {

int x=p->leer_x();

int y=p->leer_y();

p->dar_x(this->_x + x);

p->dar_y(this->_y + y);

return p;

}

Punto& Punto::suma(Punto &p) {

int x=p.leer_x();

int y=p.leer_y();

p.dar_x(this->_x + x);

p.dar_y(this->_y + y);

return p;

}

Punto& Punto::suma(Punto &p) {Punto *result;int x=p.leer_x();int y=p.leer_y();result->dar_x(this->_x + x);result->dar_y(this->_y + y);ºreturn result; //ERROR muy grave

}void main() {

Punto p1,p2(4,4);Punto *r1=p1.suma(&p2); //Primer tipoPunto r2=p1.suma(p2); //Segundo tipoPunto *r3=p1.suma(p2); //ERROR

}

Programación II 44

Operador asignación● Cuando se realiza una asignación entre objetos se debe tener

mucho cuidado, pues como se mostrará pueden existir problemas. Dos casos:

– Asignación de dos objetos estáticos con atributos dinámicos– Asignación de objetos dinámicos

● En ambos casos el problema es el mismo, pues al realizar la asignación los punteros se copian bit a bit y apuntan a la misma dirección. Si se liberará o modificará cualquiera de ellos el otro se vería seriamente afectado.

● Solución:– Objetos estáticos con atributos dinámicos: Operador de asignación– Objetos dinámicos: Usar el constructor copia

Page 12: Tema2 programacion i_ib

Programación II 45

Operador asignación II● Primer caso. Objetos estáticos

– Para todas las clases se encuentra definido por defecto el operador asignación que es utilizado automáticamente por el compilador cuando se tiene una sentencia similar a p2 = p1;

– Si tenemos atributos punteros, sobrecargar el operador asignación● Ejemplo:

Punto& operator= (const Punto & p); //DefiniciónPunto& Punto::operator= (const Punto & p) { //Implementación this->_x=p._x;this->_y=p._y; return *this;}

● El objeto que figura a la izquierda del = es el objeto que recibe el mensaje. El mensaje es el operador asignación. El objeto de la derecha es el objeto origen de la copia.

● La función termina devolviendo el propio objeto receptor.● Siempre que exista un atributo con puntero se debe generar esta

función miembro. Programación II 46

Operador Asignación III● Segundo Caso. Asignación de objetos dinámicos

– Ejemplo del problema:Punto *p, *p2;p=new Punto(4,5);p2=p; //Ambos punteros apuntan a la misma dirección !!!!!!!!!!delete p2; //¿Qué sucede con p??

– SOLUCIÓN:● El problema radica que no se ha reservado memoria para el segundo

puntero. Solución mediante el constructor copia. Punto *p, *p2;p=new Punto(4,5);p2=new Punto (*p); //Inicialización por copia.

Programación II 47

Operador this● El operador this es utilizado para referirse al objeto actual. Se

utiliza en cualquier función miembro de la clase y el compilador genera este puntero automáticamente en el proceso de compilación.

● Se trata de un operador fantasma que siempre recibe un puntero a un objeto, que es el actual.

● De este modo en cualquier función miembro se puede usar para acceder a los atributos y/o funciones miembros.

● Principalmente se utiliza en dos casos:– Cuando una función miembro con parámetros contienen nombres

similares de atributos que de parámetros. – Cuando se retorna el propio objeto

Programación II 48

Atributos estáticos● Hasta ahora cada objeto tiene su propio conjunto de atributos.

Sin embargo en algunas ocasiones nos puede interesar que los objetos de una clase compartan un mismo atributo –> Atributos estáticos.

– Por ejemplo si se quieren contar cuantos objetos hay declarados de una clase.

● De este modo un atributo estático se caracteriza :– Todos los objetos comparten este atributo– Sólo se inicializa una vez (aunque se creen N objetos)– Puede ser accedido por todos los objetos

● Para conseguir este objetivo se tiene que declarar el atributo como estático, usando la palabra reservada static

Page 13: Tema2 programacion i_ib

Programación II 49

Atributos estáticos II● Ejemplo: Reflejar en la clase el número de objetos que hay.

Class Punto {

static int cuantos; //Atributo compartido

public:

Punto() {cuantos++;} //Incremento cuando se crea

~Punto() {cuantos --;} //Decremento cuando se destruye

.....

};

int Punto::cuantos=0; Importante: Se inicializa fuera de la clasey no en los constructores, pues si no seinicializaría constantemente.

Programación II 50

Métodos constantes● Un método constante es aquel que garantiza que ningún

atributo de la clase va a ser modificado por una función miembro. Para ello se utiliza la palabra reservada const.

● Casos:– Función miembro constante. Se debe añadir la palabra reservada

detrás de los argumentos. Por ejemplo en funciones miembros que hagan listado.

void mostrar () const;– Objetos constantes: Objetos que no se pueden modificar su estado.

Sólo podrán recibir mensajes constantes.const Punto p();

– Objetos argumentos constantes: Para garantizar que dentro del objeto no se va a modificar. Ej: Argumentos por referencia constantes.

Programación II 51

Composición de clases● Los atributos de una clase pueden ser tipos de datos simples,

tipos de datos definidos u otras clases.● Composición: Crear nuevas clases a partir de clases ya

existentes que actúan como atributos de la nueva clase.● Esta nueva característica permite la creación de código a

partir de uno ya existente --> Reutilización.● La relación de composición generalmente se representa con

la frase “tiene un”.● Ejemplo: Clase Línea se encuentra formada por dos puntos.

PuntoLinea tiene un

Programación II 52

Composición de Clases II● Cuando se crea un objeto se invocan automáticamente a los

constructores de los objetos miembros:– Antes que el constructor de la clase global

– Según el orden en el que se declaren

class Punto {

.....

};

class Linea {

private:

Punto _origen, _destino; //La clase linea tiene dos puntos. Punto p[2];public:

Linea();Linea(const Punto& p1, const Punto& p2);Linea(const Linea& l);Linea& operator= (const Linea& l)

}

Page 14: Tema2 programacion i_ib

Programación II 53

Bibliografía Recomendada● Libros:

– Programación orientada a objetos. Roberto Rodríguez, Encarna Sosa y Alvaro Prieto. S004.421rodpro

– Programación en C++. Luis Joyanes. S004.43c++joy– Como programar en C++ . H. M. Deitel. S004.43C++dei– Resolución de problemas con C++. Savitch.S004.43C++sav– El lenguaje de programación C++. Stroustrup, B. S004.43C++str– Aprendiendo C++ para linux en 21 días. Jesse Liberty y David B.

Horvath.

Programación II 54

Ejemplo: Clase puntousing namespace std;

#include <iostream>

class Punto {

private:

int _x, _y; //Atributos

public:

Punto(); //Constructor por defecto

Punto (int x, int y); //Constructor parametrizado

Punto (const Punto& origen); //Constructor Copia

int leer_x() {return _x;} //Función miembro insertada

int leer_y() {return _y;} //Función miembro insertada

void dar_x(int x);

void dar_y(int y);

Punto& operator= (const Punto & p);

~Punto();

};

Punto::Punto() { cout << "Estoy en el constructor Defecto"<< endl; _x=0; _y=0; }Punto::Punto(int x, int y) { cout << "Estoy en el constructor Parametrizado"<< endl; _x=x; _y=y; }Punto::Punto (const Punto& origen) { cout << “Constructor copia” << endl; this->_x=origen._x; // dar_x(origen._x); this->_y=origen._y; // }void Punto::dar_x (int x) { this->_x=x; }void Punto::dar_y (int y) { this->_y=y; }Punto& Punto::operator= (const Punto & p) { cout << “Operador asignación” << endl; this->_x=p._x;this->_y=p._y; return *this; }Punto::~Punto() { cout<<"Estoy en el destructor"<<endl; }

Programación II 55

Ejemplo Clase Punto II

int main(){

int m;

Punto * p[2];

p[0]= new Punto(4,4); //Cualquier otro constructor

p[0]->leer_x();

cout<<"La coordenada X es: "<< p[0]->leer_x()<<endl;

cout<<"La coordenada Y es: "<< p[0]->leer_y()<<endl;

delete p[0];

Punto * p1;

p1=new Punto[2]; //Se esta llamando al constructor por defecto

p1[0].leer_x();

cout<<"La coordenada X es: "<< p1[0].leer_x()<<endl;

cout<<"La coordenada Y es: "<< p1[0].leer_y()<<endl;

delete []p1;

cin >> m;

return 0;

}

int main(){

Punto p; //DefectoPunto p1(5,4); //ParametrizadoPunto p2(3,4); //ParametrizadoPunto p4[6]; //Defecto. 6 constructorPunto p5=p2; //CopiaPunto p6(p1); //Copiap1=p2; //Asignaciónreturn 1;

}

Ejemplo1 Ejemplo2

Programación II 56

Ejemplo de Composición. Linea#ifndef linea_h // Evitar inclusiones múltiples

#define linea_h

#include "punto.hpp"

class Linea {

private:

Punto _origen, _destino;

public:

Linea(); //Constructor por defecto

Linea (const Punto &O, const Punto &D);

Linea (int x1,int y1, int x2, int y2);

Linea (const Linea& l); //Constructor Copia

Punto& leer_origen(); Punto& leer_destino();

void dar_origen(const Punto &O);

void dar_destino(const Punto &D);

void mostrar();

Linea& operator= (const Linea & l);

~Linea();

};

#endif

#include "linea.hpp"#include <iostream>Linea::Linea(){ cout << "Constructor linea por defecto" << endl; }

Linea::Linea (int x1,int y1, int x2, int y2):_origen(x1,y1),_destino(x2,y2){ cout << "Constructor linea coordenadas" << endl; }

Linea::Linea (const Punto &O, const Punto &D):_origen(O), _destino(D){ cout << "Constructor linea punto" << endl; }

Linea::Linea (const Linea& l):_origen(l._origen),_destino(l._destino){ cout << "Constructor linea copia" << endl;/* _origen=l._origen; //Otra forma de hacerlo _destino=l._destino;*/ }

Punto& Linea::leer_origen(){ return (this->_origen); }Punto& Linea::leer_destino() { return (this->_destino); }void Linea::dar_origen(const Punto &O){ _origen=O; }void Linea::dar_destino(const Punto &D) { _destino=D; }void Linea::mostrar() { _origen.mostrar(); _destino.mostrar(); }Linea& Linea::operator= (const Linea & l){ cout << "Operador asignación linea" << endl; this->_origen=l._origen;this->_destino=l._destino; return *this; }Linea::~Linea() { cout << "Destructor linea"<< endl;}

Page 15: Tema2 programacion i_ib

Programación II 57

Ejemplo de Composición. Linea II#include <iostream.h>

#include "punto.hpp"

#include "linea.hpp"

int main(){

int m;

Punto p1(4,4), p2(5,5);

Linea L(4,4,5,5);

Linea L2(L);

L2.mostrar();

Linea *L3= new Linea (5,5,6,6);

L3->mostrar();

*L3=L2; //Cuidado: No L3=&L2

L3->mostrar();

delete L3;

L2.mostrar();

L.mostrar();

cin >> m;

return 0;

}Programación II 58

Ejercicios● Implementar y desarrollar un programa principal para las

siguientes clases. Se debe definir todos sus constructores, operador =, destructor, mostrar, acceso y retorno a sus atributos.

– Hora formado por tres enteros: horas, minutos, segundos. Funcionales adicionales: suma dos objetos horas, una hora más grande que otra.

– Fecha formado por día, mes y año. Funciones adicionales: Sumar, restar dos fechas, calcular el tiempo transcurrido desde el año 1900.

– Cadena formado por un atributo dinámico (cadena) y su longitud. Funciones: longitud, acceso a una determinada posición, visualizar, primera posición de un carácter en un objeto cadena.

– Persona formado por los atributos: nombre (dinámico), edad, telefono (dinámico).

– Entero formado por un valor entero. Funciones adicionales: suma, resta, multiplicación y división.

– Complejo formado por dos valores reales. Funciones adicionales: suma, resta, multiplicación y división.

Programación II 59

Ejercicios● Composición

– Implementar la clase Rectángulo a partir de la clase Línea– Implementar la clase Rectángulo a partir de la clase Punto– Implementar de nuevo la clase persona formado por las siguientes

clases:● Nombre: Clase Cadena● Fecha Nacimiento: Clase Fecha● Edad: Clase Entero

– Definir una clase que almacene información de un vehículo formado por las siguientes clases:

● Marca: Clase Cadena● Num_Puertas: Clase entero● Potencia: Clase entero