Tema2 programacion i_ib

  • 368 views
Uploaded on

 

  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Be the first to comment
    Be the first to like this
No Downloads

Views

Total Views
368
On Slideshare
0
From Embeds
0
Number of Embeds
0

Actions

Shares
Downloads
8
Comments
0
Likes
0

Embeds 0

No embeds

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
    No notes for slide

Transcript

  • 1. Índice ● Introducción ● Declaración de una clase ● Encapsulación ● Representación gráfica de una clase ● Constructores y destructores Tema 2. Programación Orientada a Objetos ● Creación y eliminación dinámica de objetos ● Paso y retorno de objetos a funciones Programación II ● Otras características – Operador asignación – Operador this – Atributos estáticos – Métodos constantes ● Composición ● Bibliografía ● Ejemplos y ejerciciosProgramación II 1 Programación II 2 Introducción Introducción II. Historia I. ● Programación orientada a objetos: ● Las técnicas de programación han considerando distintas – ¿Qué es? entidades a lo largo del tiempo, las cuales cada vez tienen un – mayor nivel de abstracción. Parece muy lejano la ¿Para qué sirve? programación en binario, pero solamente han transcurrido 50 – ¿Por qué? años. – ¿Cómo surgió? ● Se pueden clasificar: – ¿Dónde debe usarse? – Prehistoria de la programación (maquina) – ¿Cómo debe usarse? – Programación estructurada – ..... – Programación procedimental ● La programación orientada a objetos ha surgido con motivo – Programación Modular de una evolución en la forma de desarrollar proyectos – Los tipos abstractos de datos software. – Programación orientada a objetos ● 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 3 Programación II 4
  • 2. Introducción III. Historia II Introducción III. Historia II ● Programación Estructurada ● Programación Procedimental – Introducción de una serie de estructuras de control básicas – Se basa en la idea de descomponer los programas en funciones que ● Secuencia resuelvan el problema. ● Selección – Una vez determinadas las funciones, para la solución del problema solamente se deben realizar llamadas a estas funciones. ● Iteración – Se debe definir separadamente las estructuras de datos que manejan – De este modo se construyen programas más legibles y fáciles de mantener. los programas. – Inconvenientes: – Sin duda alguna supuso un cambio bastante importante, pero los problemas complejos son difíciles de mantener. ● 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 5 Programación II 6 Introducción IV. Historia III. Introducción V. Historia IV ● Programación modular ● Tipos abstractos de datos – La idea es dividir el problema en módulos independientes qué – El objetivo es definir cuales son las estructuras de datos y definir sus representen una caja negra donde cada módulo resuelva una parte del operaciones de manipulación. problema. – Se basa en la programación modular y el objetivo es conseguir la – Dentro de cada uno de los módulos se incluyen los procedimientos y encapsulación del código y datos. funciones que proporcionen la funcionalidad deseada de ese módulo. – El objetivo es que el acceso a los datos se produzca mediante las – Con esta técnica el problema puede ser resueltos por distintas funciones aunque realmente no se consigue dicho objetivo. personas, donde cada una implementa sus módulos. – Algunos autores clasifican esta técnica como la antesala de la – Con esta programación aparecen otros conceptos: programación orientada a objetos. ● Compilación separada – El principal inconveniente radica en que conceptos como herencia, ● Interfaz de utilización de un módulo polimorfismo no se pueden contemplar en esta técnica. ● 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ónProgramación II 7 Programación II 8
  • 3. Introducción VI. Historia V. Introducción VII. Historia VI. ● Programación orientada a objetos ● Nomenclatura usada: – Metodología basada en la idea natural de la existencia de un mundo lleno de objetos. Todo es objeto software. Conceptos empleados en Técnicas Tradicionales C++ – El objetivo es identificar los objetos y definir sus comportamientos. las Técnicas Orientadas a Objetos – La solución al problema se consigue mediante una secuencia de Métodos Procedimientos, funciones o Función subrutinas miembro pasos de mensajes entre los objetos. Variables Instancia Datos Miembros Objeto , instancia Variable Objeto – Ventajas: Mensajes Llamadas a procedimientos y Llamada a funciones función ● Favorece el diseño de sistemas software complejos. Clases Tipos Abstractos de Datos Clases ● Reusabilidad: Reutilización del código Herencia No existe técnica similar Derivación Subclase No existe técnica similar Clase ● Extensibilidad: Extensión del código derivada Llamadas bajo control del Llamadas bajo el control del ● Reducir el coste de desarrollo y mantenimiento sistema programador programa=sistema de programa=secuencia de ● Mejorar la productividad de los programadores objetos interactivos instrucciones ● Sistemas más robustos y estables. – Otros conceptos: herencia, polimorfismo, vinculación dinámica,....Programación II 9 Programación II 10 Declaración de una clase Declaración de una clase II ● Antes de crear un objeto deberemos establecer su plantilla o class Nombre_clase { formato -> Clase. Ej: Punto, vehículo, televisor, persona //atributos ● Para cada clase se deben describir sus características y su //Miembros comportamiento. }; ● Una clase es la especificación de un tipo de objeto que se Ejemplo. Clase Punto encuentra formado: – class Punto { Sus características, tanto físicas como lógicas--> Atributos – int _x, _y; Su comportamiento, operaciones que se pueden realizar en una clase --> Métodos o funciones (Miembro en C++) void dibujar (); ● Debemos diferenciar claramente entre: int leer_x(); – Clase--> Plantilla de un objeto int leer_y(); – Objeto --> Ejemplares o variables de una clase. void dar_x(int x); void dar_y(int y); };Programación II 11 Programación II 12
  • 4. Declaración de una clase III Declaración de una clase IV ● Implementación de las funciones miembros: Dos tipos: ● Cada variable que se declara de una clase se conoce como – Funciones miembros insertadas. En la propia definición se realiza su objeto de una clase. implementación. ● Todos los objetos de una misma clase tienen las mismas – Funciones miembros fuera de la clase. Se implementan fuera de la definición de la clase. Tipo Nom_Clase::Func_Miem(Parametros) {}; características y miembros pero con diferentes valores. class Punto { ● Declaración de un objeto: int _x, _y; //Atributos void inicializar () { _x=0;_y=0;}; //Función miembro insertada Nombre_Clase obj1, obj2, ....objN; int leer_x() {return _x;} //Función miembro insertada int leer_y() {return _y;} //Función miembro insertada ● Ejemplo: Queremos declarar 3 objetos puntos: void dar_x(int x); void dar_y(int y); Punto punto_1, punto_2, punto_3; }; void Punto::dar_x (int x) { void Punto::dar_y (int y) { Implementación de las funciones miembros this->_x=x; this->_y=y; externas a su definición } }Programación II 13 Programación II 14 Declaración de una clase. V Declaración de una clase VI using namespace std; ● Los objetos se manipulan mediante el paso de mensajes. int main() { ● El funcionamiento de una aplicación OO se realiza mediante Punto p; //Declaramos un objeto de tipo punto el paso de mensajes entre las distintas instancias del mismo. int m,n; ● De este modo: cout<<”Escribe la coordenada X:”<<endl; – Los mensajes inician acciones cin >>m; – Los mensajes se envían a objetos cout<<”Escribe la coordenada y:”<<endl; – Un objeto recibe mensajes y ejecuta métodos: ocultación de cin >>n; informació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 15 Programación II 16
  • 5. Encapsulación I Encapsulación II ● Uno de los pilares básicos de la POO es la encapsulación de ● La definición anterior se ve modificada: los datos. El acceso a los datos de una clase deben realizarse class Punto { de forma controlada, protegiéndolos de acceso no autorizados. private: int _x, _y; ● De este modo, existe una ocultación de la información fuera public: de la clase. void dibujar(); ● 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 ● Los modificadores de acceso son: privadas que son usadas por las públicas. – Public: Su acceso se puede realizar desde fuera de la clase – Private: Su acceso esta limitado dentro de la clase. ● De este modo se busca que el acceso a los datos sea controlado y sólo se puede realizar mediante las funciones – Protected: Se verá posteriormente miembros. ● Ejemplo: Definir las siguientes clases: Vehículo, persona y círculo.Programación II 17 Programación II 18 Encapsulación III Encapsulación IV. Ejemplo ● A los elementos privados sólo se pueden acceder desde ● Ejemplo Clase Persona. dentro de la clase, mientras que a lo público se accede desde class Persona { cualquier objeto. private: ● Los atributos de una clase son datos de tipos previamente char _nombre[30]; definidos u objetos de otras clases. char _nif[10]; int _edad; ● Dentro de la clase public: – Se puede acceder a los atributos void inicializar (char *nombre, char * nif,int edad); – Se puede acceder a los métodos públicos y privados void leer_nombre(char *nombre); void leer_nif(char *nif); ● Desde un objeto void leer_edad(int edad); – No se puede acceder a los atributos privados char * dar_nombre(); char * dar_nif(); – No se puede acceder a las funciones miembros privadas int dar_edad(); – Sólo se puede acceder a las funciones miembros públicas void mostrar(); }; – Se utiliza el paso de mensaje: objeto.mensajeProgramación II 19 Programación II 20
  • 6. Encapsulación V Representación gráfica ● Convenios de denominación ● Para representar gráficamente los elementos de los programas – Los identificadores se escribirán en general en minúsculas, a OO y sus relaciones vamos a utilizar los diagramas UML que excepción, en los casos que se indique, de ciertas letras. son usados dentro de la Ingeniería del Software. – Las clases comenzarán por mayúscula: Clase, Punto, Circulo. ● Según se vayan mostrando los distintos conceptos de OO se – Los atributos comenzarán por subrayado: _x, _y. presentará su representación UML. – Los métodos comenzarán por minúscula. Aquellos que sean ● Representación de una clase específico de un determinado atributo llevarán un guión: leer_x (), leer_y(). Punto – Los objetos comenzarán por minúscula: objeto1, punto. Nombre_Clase _x:int _y:int – Los identificadores compuestos por varias palabras: la segunda y siguientes palabras llevarán su primera letra en mayúscula: Atributos Inicializar(x:int,y:int):void dar_x:int listaPuntos, vectorPuntos. Métodos dar_y:int leer_x(x:int):void leer_y(y:int):void ● Se pueden omitir alguna de las secciones o dejarse en blancoProgramación II 21 Programación II 22 Constructores y Destructores Constructores y Destructores II ● Tal y como se ha podido comprobar la declaración de objetos ● Constructor: Función miembro encargada de inicializar las se realiza de la misma forma que para el resto de las instancias de clase cuando estas son creadas. variables. ● Los constructores deben tener el mismo nombre que la clase y ● De forma que cuando se necesita, primero se crea la variable nunca puede devolver ningún tipo de dato. y posteriormente se destruye. ● Los constructores deben definirse dentro de la sección pública, ● Pero en la POO existe una peculiaridad. Cuando se crea un pues sino, no se tendría acceso a los mismos. objeto se produce una llama de forma automática a un ● Sintaxis: método especial denominado constructor. class Nombre_Clase { ● Y cuando se destruye se realiza otra llamada automática al nombre_clase::nombre_clase(parámetros); //Definición Constructor destructor. ..... ● Si nosotros no lo proporcionamos, el compilador generará }; unos por defecto, pero como veremos posteriormente esta nombre_clase::nombre_clase(parámetros) { //Implementación situación no es realmente conveniente. }Programación II 23 Programación II 24
  • 7. Constructores y Destructores III Constructores y Destructores IV ● Ejemplo ● A veces es necesario poder inicializar los objetos de distintas class Punto { formas. Por ejemplo, disponer un constructor que los public: inicialice a un valor por defecto o un constructor que recibe por parámetros los valores de cada uno de los atributos. --> Punto(); //Constructor. Definición. Sobrecarga de funciones. ..... }; ● La sobrecarga de funciones nos permite definir funciones con el mismo nombre pero con distinta signatura (número y tipo Punto::Punto() { //Constructor. Implementación de parámetros). cout << “Estoy en el constructor”<< endl; _x=0; _y=0; ● 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 int main() { constructores parametrizados para una clase. Punto p; //Se produce la llamada al constructor automáticamente ..... };Programación II 25 Programación II 26 Constructores y Destructores V Constructores y Destructores VI Class Punto { Punto(); //Constructor por defecto ● En las clases debe existir un constructor por defecto, que no Punto(int a, int b); //Constructor parametrizado *** tenga argumentos, y este se invoca siempre que se crea un Punto (int a); //Constructor parametrizado objeto (si no es con parámetros). ..... }; ● Si no se proporciona uno, el compilador genera int main() { automáticamente un constructor por defecto. Punto p; //Llamada constructor por defecto Punto p1(5); //Llamada constructor parametrizado Punto p2 = Punto(2,3); //Llamada constructor parametrizado ● Este constructor funcionará correctamente siempre y cuando Punto p3[6]; //Vector de puntos. Constructor parametrizado para cada posición 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. ***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 27 Programación II 28
  • 8. Constructores y Destructores VII Constructores y Destructores VIII ● Destructores: Función miembro encargada de “destruir” ● Constructor copia toda la información asociada a una instancia de una clase, – Existe otro constructor muy importante en la OO, el cual es utilizado principalmente si se había reservado memoria. cuando se crea un objeto a partir de otro. ● Igual que el constructor: – Igual que con el constructor por defecto, si no se proporciona uno el compilador genera uno. – Es invocado automáticamente por el compilador – El constructor copia por defecto copia bit a bit los atributos de la – No tiene argumentos instancia copiada. ● Importante: Sólo puede existir uno por clase – Este constructor funciona correctamente siempre y cuando no ● Sintaxis: 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 ~Nombre_Clase(); dirección. ● Ejemplo: ● Ejemplo: ~Punto(); Punto p(10,10); //Constructor parametrizado ~Persona(); 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 p2Programación II 29 Programación II 30 Constructores y Destructores IX Constructores y Destructores X ● 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) {......} Persona p1; Persona p1; Juan Juan – Cuando una función retorna un objeto como valor de retorno. Al terminar char * Nombre char * Nombre la ejecución se crea una copia del objeto que se devuelve. Punto fx(....) { Persona p2=p1 Persona p2=p1 Punto x; return x; } Persona p2; Persona p2; Juan ● En estos casos, como se crea una copia del objeto bit a bit que char * Nombre char * Nombre 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? Constructor Copia por defecto Constructor CopiaProgramación II 31 Programación II 32
  • 9. Constructores y Destructores XI Constructores y Destructores XII ● Implementación del constructor copia de la clase Persona ● Resumen: Persona::Persona(const Persona& origen) { nombre= new char[strlen(origen.mensaje)+1]; Constructor copia Para cada clase que definamos siempre se crearán los siguientes strcpy(nombre,origen.nombre); objetos } – Constructor por defecto – Constructor copia Persona::Persona (char *nom) { nombre=new char [strlen(nom)+1]; – Constructor parametrizado (Opcional) Reserva de memoria en el strcpy(nombre,nom); constructor – Operador asignación “=” (Se presentará posteriormente) } – Destructor (Aunque en algunas ocasiones no realice ninguna Persona::~Persona() { operación) if (nombre) { delete [] nombre; Liberación de la memoria nombre=NULL; } }Programación II 33 Programación II 34 Creación y eliminación dinámica de objetos Creación y eliminación dinámica de objetos II ● Como cualquier otra variable, existen dos formas de crear un ● Como para el resto de variables dinámicas en C++ se utilizan objeto: los operadores new y delete. – Estáticamente: Los objetos son creados y destruidos cuando ha ● Un objeto dinámico como cualquier variable dinámica tiene terminado su ámbito. El compilador controla su ciclo de vida. el siguiente ciclo de vida: – Dinámicamente: El programador es el encargado de controlar su – Definir el puntero a un objeto creación y destrucción. Punto * p; p Punto X:int ● ¿Porque se necesita objetos dinámicos si con los estáticos y:int Inicializar(x:int,y:int):void – Reservar la memoria e inicializar el objeto (Constructor) DarX:int puedo trabajar bien? DarY:int LeerX(x:int):void p= new Punto(); p LeerY(y:int):void – Sólo se reserva memoria cuando se necesita – Utilizar el objeto – Se liberan los objetos cuando ya no se necesitan, mientras que del otro mecanismo es el compilador quien los libera cuando termina su p->leer_x(); ámbito. – Liberar la memoria reservada por el objeto ● Ejemplo: Para almacenar 100 puntos, existen dos opciones delete (p); un vector de puntos (se reserva la memoria para 100 puntos) o mediante programación dinámica, donde según se necesitaProgramación II un punto se reserva memoria para él. 35 Programación II 36
  • 10. Creación y eliminación dinámica de objetos III Creación y Eliminación dinámica de objetos IV ● Vector de objetos. Dos formas: – Estática: Punto p[10]; ● Precauciones a tener con los punteros: – Dinámica. Utilizando los operadores new y delete. Dos soluciones. – Siempre reservar memoria cuando se vaya a usar. Si se intenta ● Primera acceder al contenido apuntado por un puntero sin haber reservado – memoria puede ser catastrófico. Punto * p[2]; – p[0]= new Punto(4,4); //Cualquier otro constructor – p[0]->leer_x(); – Intentar liberar dos veces un puntero – cout<<"La coordenada X es: "<< p[0]->leer_x()<<endl; – cout<<"La coordenada Y es: "<< p[0]->leer_y()<<endl; – Intentar liberar un puntero para el cual no se ha liberado memoria – delete p[0]; ● Segunda – Punto * p1; – No liberar el espacio reservado – 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;Programación II – delete []p1; 37 Programación II 38 Paso y retorno de objetos a funciones Paso y retorno de objetos a funciones II ● Los objetos como cualquier otra variable se pueden pasar a ● Paso de objetos por valor: las funciones. Existen principalmente dos formas: – Igual que con las variables se produce una copia del objeto – Por valor: El compilador genera una copia de la variable y es – Importante: Esto implica una llamada al constructor copia y una utilizada en la función. llamada al destructor cuando finaliza su ámbito. – Por referencia: No se le pasa la variable sino una referencia de la – Problemas: misma (más eficiente y permite modificar el contenido). Dos formas: ● Si no tenemos definido el constructor copia y se ejecuta el por defecto, ● Como puntero (Heredado de C) se tienen problemas con atributos a punteros. ● Como referencia (C++) ● Además parece poco eficiente pues se tiene que crear un objeto y Ejemplo (int x, int *y, int &z) destruirlo. ● Los objetos pueden ser pasados mediante estos tres métodos. – Solución: A continuación se exponen las ventajas e inconvenientes de ● Usar paso por referencias constantes para pasar objetos por valor. cada uno de ellos.Programación II 39 Programación II 40
  • 11. Paso y retorno de objetos a funciones III Paso y retorno de objetos a funciones IV ● Paso por referencia (retorno por argumento) ● Funciones que retornan objetos. Dos mecanismos: – Con este método no se produce una copia del objeto en su invocación – Por valor. sino que se pasa una referencia del objeto. Ventajas: – Por referencia (Puntero y referencias). ● Eficiencia ● En ambos casos, se deben tener ciertas precauciones y ● Permite la modificación del objeto asegurarse de: – Inconveniente: – Tener un constructor copia ● En ocasiones nos puede interesar solo tener acceso de lectura al objeto y no de modificación. --> Paso de referencia constante – Tener un operador asignación class Punto { – Nunca devolver un objeto local creado en la función miembro: ...... ● Se recomienda devolver un objeto por argumento, pues Punto(const Punto &P); /*Constructor copia. Utiliza la palabra reservada const muchos de los problemas originados mediante “return” 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.*/ se resuelven. void Sumar_Punto (Punto& p); /*El objeto p puede modificarse dentro de la función.*/ }Programación II 41 Programación II 42 Paso y retorno de objetos a funciones V Operador asignación ● Ejemplo: ● Cuando se realiza una asignación entre objetos se debe tener Punto * Punto::suma(Punto *p) { Punto& Punto::suma(Punto &p) { mucho cuidado, pues como se mostrará pueden existir Punto *result; int x=p->leer_x(); int x=p.leer_x(); problemas. Dos casos: int y=p.leer_y(); int y=p->leer_y(); – Asignación de dos objetos estáticos con atributos dinámicos result->dar_x(this->_x + x); p->dar_x(this->_x + x); result->dar_y(this->_y + y);º – Asignación de objetos dinámicos return result; //ERROR muy grave p->dar_y(this->_y + y); } return p; void main() { ● En ambos casos el problema es el mismo, pues al realizar la } Punto p1,p2(4,4); Punto *r1=p1.suma(&p2); //Primer tipo asignación los punteros se copian bit a bit y apuntan a la Punto& Punto::suma(Punto &p) { Punto r2=p1.suma(p2); //Segundo tipo misma dirección. Si se liberará o modificará cualquiera de Punto *r3=p1.suma(p2); //ERROR int x=p.leer_x(); } ellos el otro se vería seriamente afectado. int y=p.leer_y(); ● Solución: p.dar_x(this->_x + x); – Objetos estáticos con atributos dinámicos: Operador de asignación p.dar_y(this->_y + y); – Objetos dinámicos: Usar el constructor copia return p; }Programación II 43 Programación II 44
  • 12. Operador asignación II Operador Asignación III ● Primer caso. Objetos estáticos ● Segundo Caso. Asignación de objetos dinámicos – Para todas las clases se encuentra definido por defecto el operador – Ejemplo del problema: asignación que es utilizado automáticamente por el compilador cuando se Punto *p, *p2; tiene una sentencia similar a p2 = p1; p=new Punto(4,5); – Si tenemos atributos punteros, sobrecargar el operador asignación p2=p; //Ambos punteros apuntan a la misma dirección !!!!!!!!!! ● Ejemplo: delete p2; //¿Qué sucede con p?? Punto& operator= (const Punto & p); //Definición – SOLUCIÓN: Punto& Punto::operator= (const Punto & p) { //Implementación this->_x=p._x;this->_y=p._y; return *this; ● El problema radica que no se ha reservado memoria para el segundo puntero. Solución mediante el constructor copia. } Punto *p, *p2; ● El objeto que figura a la izquierda del = es el objeto que recibe el p=new Punto(4,5); mensaje. El mensaje es el operador asignación. El objeto de la p2=new Punto (*p); //Inicialización por copia. 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 estaProgramación II función miembro. 45 Programación II 46 Operador this Atributos estáticos ● El operador this es utilizado para referirse al objeto actual. Se ● Hasta ahora cada objeto tiene su propio conjunto de atributos. utiliza en cualquier función miembro de la clase y el Sin embargo en algunas ocasiones nos puede interesar que compilador genera este puntero automáticamente en el los objetos de una clase compartan un mismo atributo –> proceso de compilación. Atributos estáticos. ● Se trata de un operador fantasma que siempre recibe un – Por ejemplo si se quieren contar cuantos objetos hay declarados de puntero a un objeto, que es el actual. una clase. ● De este modo en cualquier función miembro se puede usar ● De este modo un atributo estático se caracteriza : para acceder a los atributos y/o funciones miembros. – Todos los objetos comparten este atributo – Sólo se inicializa una vez (aunque se creen N objetos) ● Principalmente se utiliza en dos casos: – Puede ser accedido por todos los objetos – Cuando una función miembro con parámetros contienen nombres similares de atributos que de parámetros. ● Para conseguir este objetivo se tiene que declarar el atributo – Cuando se retorna el propio objeto como estático, usando la palabra reservada staticProgramación II 47 Programación II 48
  • 13. Atributos estáticos II Métodos constantes ● Ejemplo: Reflejar en la clase el número de objetos que hay. ● Un método constante es aquel que garantiza que ningún atributo de la clase va a ser modificado por una función Class Punto { miembro. Para ello se utiliza la palabra reservada const. static int cuantos; //Atributo compartido ● Casos: public: – Función miembro constante. Se debe añadir la palabra reservada detrás de los argumentos. Por ejemplo en funciones miembros que Punto() {cuantos++;} //Incremento cuando se crea hagan listado. ~Punto() {cuantos --;} //Decremento cuando se destruye void mostrar () const; ..... – Objetos constantes: Objetos que no se pueden modificar su estado. }; Sólo podrán recibir mensajes constantes. int Punto::cuantos=0; Importante: Se inicializa fuera de la clase const Punto p(); y no en los constructores, pues si no se – Objetos argumentos constantes: Para garantizar que dentro del objeto inicializaría constantemente. no se va a modificar. Ej: Argumentos por referencia constantes.Programación II 49 Programación II 50 Composición de clases Composición de Clases II ● Los atributos de una clase pueden ser tipos de datos simples, ● Cuando se crea un objeto se invocan automáticamente a los tipos de datos definidos u otras clases. constructores de los objetos miembros: – Antes que el constructor de la clase global ● Composición: Crear nuevas clases a partir de clases ya – Según el orden en el que se declaren existentes que actúan como atributos de la nueva clase. ● Esta nueva característica permite la creación de código a class Punto { partir de uno ya existente --> Reutilización. ..... ● La relación de composición generalmente se representa con }; la frase “tiene un”. class Linea { ● Ejemplo: Clase Línea se encuentra formada por dos puntos. private: Punto _origen, _destino; //La clase linea tiene dos puntos. Punto p[2]; Linea Punto public: tiene un Linea(); Linea(const Punto& p1, const Punto& p2); Linea(const Linea& l); Linea& operator= (const Linea& l)Programación II 51 Programación II 52 }
  • 14. Bibliografía Recomendada Ejemplo: Clase punto using namespace std; Punto::Punto() { ● Libros: cout << "Estoy en el constructor Defecto"<< endl; #include <iostream> _x=0; _y=0; } – Programación orientada a objetos. Roberto Rodríguez, Encarna Sosa Punto::Punto(int x, int y) { cout << "Estoy en el constructor Parametrizado"<< endl; y Alvaro Prieto. S004.421rodpro class Punto { _x=x; _y=y; } Punto::Punto (const Punto& origen) { – Programación en C++. Luis Joyanes. S004.43c++joy private: cout << “Constructor copia” << endl; this->_x=origen._x; // dar_x(origen._x); – Como programar en C++ . H. M. Deitel. S004.43C++dei int _x, _y; //Atributos this->_y=origen._y; // } public: void Punto::dar_x (int x) { – Resolución de problemas con C++. Savitch.S004.43C++sav this->_x=x; } Punto(); //Constructor por defecto void Punto::dar_y (int y) { this->_y=y; } – El lenguaje de programación C++. Stroustrup, B. S004.43C++str Punto (int x, int y); //Constructor parametrizado Punto& Punto::operator= (const Punto & p) { cout << “Operador asignación” << endl; – Aprendiendo C++ para linux en 21 días. Jesse Liberty y David B. Punto (const Punto& origen); //Constructor Copia this->_x=p._x;this->_y=p._y; return *this; } Horvath. int leer_x() {return _x;} //Función miembro insertada Punto::~Punto() { cout<<"Estoy en el destructor"<<endl; } 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(); };Programación II 53 Programación II 54 Ejemplo Clase Punto II Ejemplo de Composición. Linea #ifndef linea_h // Evitar inclusiones múltiples #include "linea.hpp" Ejemplo1 Ejemplo2 #include <iostream> #define linea_h Linea::Linea(){ int main(){ int main(){ cout << "Constructor linea por defecto" << endl; } #include "punto.hpp" Punto p; //Defecto int m; class Linea { Linea::Linea (int x1,int y1, int x2, int y2):_origen(x1,y1),_destino(x2,y2){ Punto p1(5,4); //Parametrizado cout << "Constructor linea coordenadas" << endl; } Punto * p[2]; private: Punto p2(3,4); //Parametrizado Punto p4[6]; //Defecto. 6 constructor p[0]= new Punto(4,4); //Cualquier otro constructor Linea::Linea (const Punto &O, const Punto &D):_origen(O), _destino(D){ Punto _origen, _destino; cout << "Constructor linea punto" << endl; } Punto p5=p2; //Copia Punto p6(p1); //Copia p[0]->leer_x(); public: p1=p2; //Asignación Linea::Linea (const Linea& l):_origen(l._origen),_destino(l._destino){ cout<<"La coordenada X es: "<< p[0]->leer_x()<<endl; Linea(); //Constructor por defecto cout << "Constructor linea copia" << endl; return 1; } cout<<"La coordenada Y es: "<< p[0]->leer_y()<<endl; /* _origen=l._origen; //Otra forma de hacerlo Linea (const Punto &O, const Punto &D); _destino=l._destino;*/ } delete p[0]; Linea (int x1,int y1, int x2, int y2); Punto& Linea::leer_origen(){ Punto * p1; Linea (const Linea& l); //Constructor Copia return (this->_origen); } Punto& Linea::leer_destino() { p1=new Punto[2]; //Se esta llamando al constructor por defecto Punto& leer_origen(); Punto& leer_destino(); return (this->_destino); } p1[0].leer_x(); void Linea::dar_origen(const Punto &O){ void dar_origen(const Punto &O); _origen=O; } cout<<"La coordenada X es: "<< p1[0].leer_x()<<endl; void Linea::dar_destino(const Punto &D) { void dar_destino(const Punto &D); _destino=D; } cout<<"La coordenada Y es: "<< p1[0].leer_y()<<endl; void Linea::mostrar() { void mostrar(); delete []p1; _origen.mostrar(); Linea& operator= (const Linea & l); _destino.mostrar(); } cin >> m; Linea& Linea::operator= (const Linea & l){ ~Linea(); cout << "Operador asignación linea" << endl; return 0; this->_origen=l._origen;this->_destino=l._destino; return *this; } }; Linea::~Linea() { }Programación II 55 #endif Programación II cout << "Destructor linea"<< endl; 56 }
  • 15. Ejemplo de Composición. Linea II Ejercicios #include <iostream.h> ● Implementar y desarrollar un programa principal para las #include "punto.hpp" siguientes clases. Se debe definir todos sus constructores, #include "linea.hpp" operador =, destructor, mostrar, acceso y retorno a sus atributos. int main(){ – Hora formado por tres enteros: horas, minutos, segundos. Funcionales int m; adicionales: suma dos objetos horas, una hora más grande que otra. Punto p1(4,4), p2(5,5); Linea L(4,4,5,5); – Fecha formado por día, mes y año. Funciones adicionales: Sumar, restar Linea L2(L); dos fechas, calcular el tiempo transcurrido desde el año 1900. L2.mostrar(); – Cadena formado por un atributo dinámico (cadena) y su longitud. Linea *L3= new Linea (5,5,6,6); Funciones: longitud, acceso a una determinada posición, visualizar, L3->mostrar(); primera posición de un carácter en un objeto cadena. *L3=L2; //Cuidado: No L3=&L2 – Persona formado por los atributos: nombre (dinámico), edad, telefono L3->mostrar(); (dinámico). delete L3; – Entero formado por un valor entero. Funciones adicionales: suma, resta, L2.mostrar(); multiplicación y división. L.mostrar(); – Complejo formado por dos valores reales. Funciones adicionales: suma, cin >> m; resta, multiplicación y división. return 0;Programación II 57 Programación II 58 } 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 enteroProgramación II 59