Logo Studenta

Guía de Prácticas de Lenguajes de Programación II N 05 - 2023 (1) - Sthefany Alegre

¡Este material tiene más páginas!

Vista previa del material en texto

Laboratorio de Programación II Página 55 
 
Mgter. Ángel Montesinos Sesión N° 03 
UNIVERSIDAD CATÓLICA DE SANTA MARÍA 
PROGRAMA PROFESIONAL DE INGENIERÍA DE SISTEMAS 
SESIÓN N° 05: 
Autorreferencias, Constructores, Destructores y Objetos 
Miembros de Clase 
I 
OBJETIVOS 
❖ Aplicar en la construcción de programas las estructuras y sus recursos para la manipulación, 
organización y almacenamiento de datos. 
❖ Diseñar programas con eficiente manipulación y organización de datos. 
❖ Revisar los conceptos involucrados en los temas de estructuras. 
❖ Evaluar los conocimientos de los alumnos en estructuras. 
II 
TEMAS A TRATAR 
❖ Introducción. 
❖ referencias 
❖ Constructores 
❖ Destructores 
❖ ¿Cómo se declara un objeto como miembro de clase? 
❖ Inicialización de miembros de clase 
❖ Resumen 
III 
MARCO TEORICO 
1. INTRODUCCIÓN 
La Programación Orientada a Objetos ofrece recursos muy versátiles para la manipulación de 
objetos, además, en cada lenguaje de programación se ofrecen recursos adicionales que le ponen 
el sello particular de optimización al diseño del código; una de estos recursos son las auto 
referencias, el uso de las mismas permite el encadenamiento en la llamada de los métodos, 
recursos que puede resultar un tanto extraños para un programador novato, pero ofrecen 
simplicidad y ahorro de líneas de código en su uso para la codificación. 
Las referencias fueron introducidas en Lenguaje C++ como una forma de hacer uso de 
recursos(variables) mediante un alias con implicaciones de uso directo de memoria, un recurso que 
pretende simplificar el uso de punteros pero no deja de lado el uso directo recurso almacenado en 
memoria. A parte de las referencias debemos hacer uso del puntero implícito this, un puntero de 
dichas características se usa al interior de la declaración de clase para hacer referencia al objeto 
que envía el mensaje y para el cual se ejecuta el método. 
El proceso de diseñar una clase con lleva la idea de crear un nuevo tipo de dato para una aplicación 
que tendrá características que no poseen los tipos de datos primitivos ni agregados existentes, la 
principal tarea es la de proveer un conjunto determinado de atributos y métodos que de forma 
completa nos proporcionen la forma de representar una entidad concreta; al crear los objetos que 
pertenecen a dicha clase se pasa por tres fases bien definidas, la primera es la instanciación del 
objeto, en donde se le asigna el espacio en memoria al objeto en creación, la segunda es la 
asignación de recursos, en donde se provee recursos de memoria o de algún tipo especial a 
Laboratorio de Programación II Página 56 
 
Mgter. Ángel Montesinos Sesión N° 03 
atributos como punteros o manejadores de archivos y la tercera es la iniciación, donde se debe 
garantizar que los objetos aparezcan en la aplicación con los valores correctos. [ 1 ][ 2 ] 
Los constructores llevan a cabo estas tres labores, es tan importante su ejecución que de carecer 
de un constructor definido por el programador, el compilador asigna uno llamado implícito, 
normalmente los constructores son invocados al momento de crear el objeto, dicha invocación se 
hace de forma implícita, pero también es posible que el programador los invoque explícitamente. 
Los destructores llevan a cabo el proceso contrario a los destructores, están encargados de hacer 
que los objetos creados sean adecuadamente eliminados de la aplicación, este punto se refiere al 
punto donde los objetos dejan de tener sentido, que normalmente es cuando se abandona el ámbito 
de creación del objeto, eso implica además que si el objeto tiene recursos de memoria dinámica 
asignados deben ser liberados por un destructor explícito que se encargue de ello, los constructores 
llevan a cabo el proceso de liberar todos los recursos ocupados por el objeto en su creación y 
existencia. 
El lenguaje C++ está diseñado de tal forma que podamos construir representaciones bastante 
complejas de la realidad que modelamos en los programas; si pensamos en términos de 
Programación Orientada a Objetos nos daremos cuenta que el mundo real es más complejo de lo 
que a veces conceptualizamos mediante las clases, por ejemplo la mayor parte de objetos es parte 
de otro objeto, es decir que en la definición de una clase tendremos como miembro dato a un objeto 
de otra clase, este fenómeno se representa en términos de los conceptos de agregación y 
composición, aunque al escribir el código no existe una diferencia práctica en la representación de 
ambas propiedades si embargo en el proceso de análisis es vital hacer la diferencia porque de esa 
forma se concibe la naturaleza de la clase que se modela y la forma como se conciben los objetos. 
[ 1 ][ 2 ] 
El incluir como atributo miembro de una clase a un objeto nos enfrentamos a cierto número de 
requerimientos de funcionamiento de las aplicaciones, el primero se refiere a la propiedad de 
lenguaje C++ que exige que cualquier identificador usado para declarar un recurso debe estar 
previamente declarado en el programa, esto nos lleva a considerar que si construimos una clase 
con un objeto de otra clase como miembro dicha clase, se debe tener previamente declarada la 
clase de la cual declaramos al objeto como miembro y el nombre de dicha clase debe estar al 
alcance dentro del ámbito de definición de nuestra clase compuesta, al hacer definiciones de clases 
en archivos independientes de cabecera debemos colocar una instrucción include que nos permita 
el acceso a dicho archivo de cabecera; El segundo aspecto se refiere a la forma como debemos 
inicializar al objeto miembro, esto es complicado porque no podemos hacer que los constructores 
del objeto miembro sean invocados de forma explícita, por lo que usaremos listas de inicialización 
para que los constructores del objeto sean adecuadamente provistos de los parámetros de 
inicialización. 
2. REFERENCIAS 
Las referencias son recursos que se usan como un identificador alternativo para un objeto. El 
principal uso que se les aplica es para enviar objetos como parámetros de métodos y como valores 
de retorno, tanto en funciones como en la sobrecarga de operadores. De forma general la notación 
&x se lee como referencia a x. [ 1 ][ 2 ] 
La forma de hacer uso de las referencias es la siguiente: 
 
 int variableEntera = 0; 
 float variableFlotante = 0; 
 int& referenciaVariableEntera; 
 referenciaVariableEntera = variableEntera; 
 float& referenciaVariableFlotante = variableFlotante; 
 
La referencia se declara anteponiéndole el operador & al nombre de la referencia, al igual que con 
los punteros la referencia debe de ser del mismo tipo del recurso referenciado. 
Inicializar la referencia significa que ha sido ligada a un objeto dato y a partir de ese momento actúa 
como si fuera un alias del recurso, es decir que si queremos manipular el recurso podemos hacerlo 
mediante su identificador inicial o por medio de la referencia. En el ejemplo se aprecia que una vez 
declarada la referencia a ésta se le asigna el nombre de la variable. La otra forma se en la que se 
define es asignándole la variable al momento de la declaración. [ 1 ][ 2 ] 
Una vez inicializada la referencia se puede manipular la variable referenciada a través de la misma: 
 
Laboratorio de Programación II Página 57 
 
Mgter. Ángel Montesinos Sesión N° 03 
 // igual que variableEntera = 3 
 referenciaVariableEntera = 3; 
 
 // igual que variableFlotante = 6.3 
 referenciaVariableFlotante = 6.3 
 
A. PUNTERO IMPLÍCITO THIS 
El recurso es utilizado para hacer referencia al objeto para el cual fue invocado el método, se dice 
que es implícito porque no es necesario incluirlo en la especificación de código pero el puntero está 
presente, su forma de uso es la siguiente: 
 
 // Codigo 3.01: practica3_01.cpp 
 // demostración deluso del puntero implícito this. 
 
 #include <iostream> 
 using namespace std; 
 
 classClase 
 { 
 int variableEntera; 
 float variableFlotante; 
 public: 
 Clase() 
 { 
 variableEntera = 0; 
 variableFlotante = 0; 
 } 
 int getVariableEntera() 
 { 
 return this -> variableEntera; 
 } 
 float getVariableFlotante() 
 { 
 return this -> variableFlotante; 
 } 
 }; 
 
 int main() 
 { 
 Clase objeto; 
 cout << objeto.getVariableEntera() << endl; 
 cout << objeto.getVariableFlotante() << endl; 
 system("pause"); 
 return 0; 
 } 
 
Se puede apreciar que en los métodos de la clase se hace uso del puntero implícito this, pero sin 
embargo si no se coloca no hay ninguna diferencia, el puntero se refiere al objeto que invoca al 
método en este caso a objeto. 
B. AUTO REFERENCIAS 
Las autoreferencias se aplican para encadenar métodos para su ejecución, algunas veces resulta 
muy interesante llamar a ejecución a un conjunto de métodos los cuales retornan una referencia al 
objeto de clase que se está usando para llamar a la operación, un ejemplo sería el siguiente: 
 
 // Codigo 3.02: practica3_02.cpp 
 // demostración del uso de las autoreferencias. 
 
 #include <iostream> 
 using namespace std; 
Laboratorio de Programación II Página 58 
 
Mgter. Ángel Montesinos Sesión N° 03 
 
 class Clase 
 { 
 int variableEntera; 
 float variableFlotante; 
 public: 
 Clase() 
 { 
 variableEntera = 0; 
 variableFlotante = 0; 
 } 
 int getVariableEntera() 
 { 
 return this -> variableEntera; 
 } 
 float getVariableFlotante() 
 { 
 return this -> variableFlotante; 
 } 
 Clase& sumaEntero(int n) 
 { 
 variableEntera += n; 
 return *this; 
 } 
 Clase& sumaFlotante(float n) 
 { 
 variableFlotante += n; 
 return *this; 
 } 
 }; 
 
 int main() 
 { 
 Clase objeto; 
 cout << objeto.getVariableEntera() << endl; 
 cout << objeto.getVariableFlotante() << endl; 
 objeto.sumaEntero(5).sumaFlotante(3.5); 
 cout << objeto.getVariableEntera() << endl; 
 cout << objeto.getVariableFlotante() << endl; 
 system("pause"); 
 return 0; 
 } 
 
Cuando tenemos un grupo de métodos que se utilizan para modificar el estado del objeto y 
generalmente no tienen un valor de retorno, podemos hacer que dicho valor de retorno sea una 
referencia al objeto de la clase, en este caso ese objeto de la clase del que hablamos es manejado 
a través del puntero implícito this, que es el que finalmente se devuelve, bajo este esquema 
podemos encadenar los métodos para su ejecución como se muestra en el ejemplo. 
3. CONSTRUCTORES 
Son métodos especiales encargados de la adecuada creación de los objetos, se invocan 
implícitamente al crear un objeto, llevan el mismo nombre de la clase y no devuelven valores de 
retorno ni los especifican; una clase puede tener tantos constructores como formas de iniciar objetos 
necesite. 
Si la clase no tiene un constructor proporcionado por el programador el compilador le proporciona 
uno, pero se corre el riesgo de que no inicialice los atributos de los objetos instanciados, como 
ejemplo el siguiente cñodigo: 
 
 // Codigo 3.03: practica3_03.cpp 
 // demostración del uso de las autoreferencias. 
 
 #ifndef CLASEEJEMPLO_H 
 #define CLASEEJEMPLO_H 
Laboratorio de Programación II Página 59 
 
Mgter. Ángel Montesinos Sesión N° 03 
 
 class ClaseEjemplo 
 { 
 private: 
 int atributoEntero; 
 char atributoChar; 
 public: 
 ClaseEjemplo(int i) 
 { 
 atributoEntero = i; 
 atributoChar = ' '; 
 } 
 ClaseEjemplo(int i = 0, char c = ' ') 
 { 
 atributoEntero = i; 
 atributoChar = c; 
 } 
 void mostrar() 
 { 
 cout << "atributoEntero: " << atributoEntero << endl; 
 cout << "atributoChar: " << atributoChar << endl; 
 } 
 }; 
 #endif 
 
La clase anterior registra dos constructores el segundo constructor usa parámetros por defecto, el 
primero debe diferenciarse del segundo en la lista de argumentos, no colocar argumentos en el 
primero causaría ambigüedad en la llamada implícita. 
 
 // Codigo 3.04: practica3_04.cpp 
 // demostración del uso de las autoreferencias. 
 
 #ifndef OTRACLASEEJEMPLO_H 
 #define OTRACLASEEJEMPLO_H 
 
 class OtraClaseEjemplo 
 { 
 private: 
 int atributoEntero; 
 char atributoChar; 
 public: 
 void mostrar() 
 { 
 cout << "atributoEntero: " << atributoEntero << endl; 
 cout << "atributoChar: " << atributoChar << endl; 
 } 
 }; 
 #endif 
 
Esta segunda clase carece de constructor explícito, al instanciar objetos los atributos no reciben 
valores y se inicializan con los valores existentes en las posiciones de memoria que les asignen. 
 
 // Codigo 3.05: practica3_05.cpp 
 // demostración del uso de las autoreferencias. 
 
 #include <iostream> 
 using namespace std; 
 
 #include "claseejemplo.h" 
 #include "otraclaseejemplo.h" 
 
 int main() 
 { 
 ClaseEjemplo objetoUno; 
Laboratorio de Programación II Página 60 
 
Mgter. Ángel Montesinos Sesión N° 03 
 ClaseEjemplo objetoDos(4,'e'); 
 OtraClaseEjemplo objetoTres; 
 cout << "objetoUno: " << endl; 
 objetoUno.mostrar(); 
 cout << "objetoDos: " << endl; 
 objetoDos.mostrar(); 
 cout << "objetoTres: " << endl; 
 objetoTres.mostrar(); 
 system("pause"); 
 return 0; 
 } 
 
El objetoTres no tiene sus atributos inicializados correctamente como se mostrará en la impresión. 
C. INVOCACIÓN DE CONSTRUCTORES 
Los constructores se invocan implícitamente al construir los objetos: 
 
 // Invocación implícita del constructor 
 ClaseEjemplo objetoUno; 
 // Error: invocación ilegal del constructor 
 ClaseEjemplo::ClaseEjemplo(); 
 // Error: invocación ilegal del constructor 
 ClaseEjemplo objetoDos = ClaseEjemplo::ClaseEjemplo(6, 'o'); 
 // Invocación legal del constructor 
 ClaseEjemplo objetoTres = ClaseEjemplo(9, 'i'); 
 // Variación sintáctica del anterior 
 ClaseEjemplo objetoCuatro(3, 'h'); 
 
Si queremos objetos dinámicos se debe de poder crearlos mediant el operador new y punteros a 
objetos del mismo tipo. 
 
 { 
 ClaseEjemplo *ptrObjetoUno = new ClaseEjemplo; 
 ClaseEjemplo *ptrObjetoDos = new ClaseEjemplo(4,'x'); 
 } 
 
Es necesario recalcar que al salir del bloque los punteros son destruidos mas no así los objetos 
dinámicos que referencian. 
D. PROPIEDADES DE LOS CONSTRUCTORES 
Los constructores son métodos especiales por lo tanto no tienen el mismo tipo de propiedades de 
los métodos convencionales: 
▪ Los constructores siempre tienen el mismo nombre de la clase a la que pertenecen. 
▪ No se pueden declarar punteros a constructores por que no se puede obtener la dirección de 
memoria de este. 
▪ Los constructores no pueden declararse virtuales por que al momento de crear al objeto se 
debe saber exactamente la forma de construcción. 
▪ Los constructores no declarar valor de retorno. 
▪ Los constructores no pueden ser heredados. 
▪ Pueden ser llamados por los constructores de las sub clases. 
▪ Una clase puede tener más de un constructor, a esto se le llama sobrecarga. 
▪ Los constructores no pueden ser declarados como friend de ninguna clase. 
▪ Los constructores pueden incluir iniciadores. 
▪ Los constructores pueden tener argumentos por defecto. 
▪ Los constructores no admiten su propia clase como argumento. 
▪ Los constructores pueden admitir referencias a su propia clase. 
Laboratorio de Programación II Página 61 
 
Mgter. Ángel Montesinos Sesión N° 03 
4. DESTRUCTORES 
Al igual que los constructores los destructores son métodos especiales cuya función es liberar los 
recursos ocupados por el objeto al momento de ser creado y de operar. Si el programador no define 
un constructor explicito, el compilador le proporciona uno, pero se hace imprescindible 
especialmente si los objetos hacen usode memoria dinámica. 
A. INVOCACIÓN EXPLÍCITA DE DESTRUCTORES 
Los destructores son invocados explícitamente de dos formas, la primera de forma indirecta 
mediante el operador delete y la segunda de forma directa usando el nombre cualificado completo 
del destructor. 
B. DECLARACIÓN DE DESTRUCTORES 
Los destructores se declaran con el mismo nombre de la clase antecedidos por el símbolo virgulilla, 
esto es para enfatizar su estrecha relación con los constructores ya que este símbolo se usa para 
indicar el complemento. 
C. INVOCACIÓN IMPLÍCITA DE DESTRUCTORES 
Cualquier variable es destruida al salir de su bloque de código de creación, esto se conoce como 
estar fuera de ámbito; es en estos casos que los destructores son invocados de forma implícita, si 
se trata d objetos globales esto ocurre al terminar la función main; para el caso de punteros no se 
llama al destructor al abandonar el bloque de creación, sin embargo los objetos dinámicos a los que 
apuntan deben ser destruidos de forma explícita llamando al operador delete. 
D. PROPIEDADES DE LOS DESTRUCTORES 
Las siguientes: 
▪ Los destructores no son heredables al igual que los constructores pueden ser invocados en 
las clases derivadas. 
▪ No se puede obtener la dirección de un destructor por lo cual no existen punteros a 
destructores. 
▪ Solo existe un destructor por clase. La destrucción de objetos se hace de la misma forma 
para todos los objetos de la clase. 
▪ Los destructores no tienen valor de retorno. 
▪ Los constructores no aceptan ningún tipo de parámetros ya que la destrucción se hace forma 
obligatoria. 
▪ En un destructor explícito las sentencias del cuerpo se ejecutan antes de destruir a los 
atributos miembros. 
▪ La invocación de los destructores se hace en orden inverso a la invocación de los 
constructores. 
▪ La destrucción de los miembros no estáticos se realiza antes que la de los miembros 
estáticos. 
▪ Los destructores no pueden ser declarados const o volatile. 
▪ Los destructores pueden ser invocados desde objetos const y volatile. 
▪ Los destructores no pueden ser declarados static ya que supone su invocación sin un objeto. 
E. DESTRUCTORES Y EL USO DE ABORT Y EXIT 
Cuando se invoca exit solo las variables globales y objetos globales serán destruidos en su orden 
normal; cuando se invoca a la función abort() no se invocan destructores ni para los objetos 
globales. 
5. ¿CÓMO SE DECLARA UN OBJETO COMO MIEMBRO DE CLASE? 
Podemos declarar a un objeto de otra clase como miembro de una clase, para ello solo debemos 
especificar su clase y luego colocar el nombre del objeto miembro que será atributo de clase. 
Laboratorio de Programación II Página 62 
 
Mgter. Ángel Montesinos Sesión N° 03 
 
 //Código 3.06: otraclase.h 
 //Declaración de una clase cualquiera 
 
 #ifndef OTRACLASE_H 
 #define OTRACLASE_H 
 
 #include <iostream> 
 using namespace std; 
 
 class otraClase 
 { 
 public: 
 otraClase(); 
 otraClase(int, float); 
 void setOtroAtributoInt(int); 
 void setOtroAtributoFloat(float); 
 int getOtroAtributoInt(int); 
 float getOtroAtributoFloat(float); 
 friend ostream& operator <<(ostream&,otraClase&); 
 private: 
 int otroAtributoInt; 
 float otroAtributoFloat; 
 }; 
 #endif 
 
Antes de declarar un objeto miembro debemos tener la clase a la cual pertenecerá, esto implica 
desarrollar la definición de clase y la definición de sus métodos. 
 
 //Código 3.06: otraclase.cpp 
 //Definición de métodos o funciones miembro de la clase otraClase 
 
 #include "otraclase.h" 
 
 #include <iostream> 
 using namespace std; 
 
 otraClase::otraClase() 
 { 
 otroAtributoInt = 0; 
 otroAtributoFloat = 0; 
 } 
 
 otraClase::otraClase(int i, float f) 
 { 
 otroAtributoInt = i; 
 otroAtributoFloat = f; 
 } 
 ostream& operator <<(ostream& salida,otraClase& obj) 
 { 
 salida << "otroAtributoInt: " << obj.otroAtributoInt << endl 
 << "otroAtributoFloat: " << obj.otroAtributoFloat << endl; 
 return salida; 
 } 
 
La clase construida anteriormente no tiene a objetos como atributos es una clase convencional. Al 
tener una clase de la cual instanciar objetos construiremos ahora una clase que tenga a objetos de 
la clase anterior como atributos bajo las tres formas de acceso. 
 
 //Código 3.07 unaclase.h 
 //Declaración de una clase que contiene objetos como miembros 
 
 #include "otraclase.h" 
 #ifndef UNACLASE_H 
Laboratorio de Programación II Página 63 
 
Mgter. Ángel Montesinos Sesión N° 03 
 #define UNACLASE_H 
 
 #include <iostream> 
 using namespace std; 
 
 class unaClase 
 { 
 public: 
 otraClase objetoPublico; 
 unaClase(); 
 unaClase(int, float, otraClase&); 
 friend ostream& operator <<(ostream&,unaClase&); 
 protected: 
 otraClase objetoProtegido; 
 private: 
 int atributoInt; 
 float atributoFloat; 
 otraClase objetoPrivado; 
 }; 
 #endif 
 
Debemos tener en cuenta que el nombre de clase debe de ser accesible desde nuestra declaración 
de clase, por lo tanto debemos incluir el archivo de cabecera que posee la definición de clase del 
objeto que estamos declarando como miembro. 
 
 //Código 3.08: unaclase.cpp 
 //Definición de métodos o funciones miembro de la clase unaClase 
 
 #include "unaclase.h" 
 #include <iostream> 
 using namespace std; 
 unaClase::unaClase() 
 { 
 atributoInt = 0; 
 atributoFloat = 0; 
 } 
 unaClase::unaClase(int i, float f, otraClase &X) : objetoPublico(X), 
 objetoProtegido(X), objetoPrivado(X) 
 { 
 atributoInt = i; 
 atributoFloat = f; 
 } 
 ostream& operator <<(ostream& salida,unaClase& obj) 
 { 
 salida << "atributoInt: " << obj.atributoInt << endl 
 << "atributoFloat: " << obj.atributoFloat << endl 
 << "objetoPublico: " << obj.objetoPublico << endl 
 << "objetoPrivado: " << obj.objetoPrivado << endl 
 << "objetoProtegido: " << obj.objetoProtegido << endl; 
 return salida; 
 } 
 
El constructor de clase puede ser por defecto o en caso contario con una lista de inicializadores, de 
esta forma los objetos miembro podrán ser inicializados correctamente. 
 
 //Código 3.08: runObjetoMiembro.cpp 
 //Implantacion de clases 
 
 #include "otraclase.h" 
 #include "unaclase.h" 
 #include <iostream> 
 using namespace std; 
 int main() 
 { 
Laboratorio de Programación II Página 64 
 
Mgter. Ángel Montesinos Sesión N° 03 
 otraClase objOtraClase(6,9); 
 unaClase objUnaClase(5,6,objOtraClase); 
 cout << objOtraClase << endl; 
 cout << objUnaClase << endl; 
 system("pause"); 
 return 0; 
 } 
 
Salida: 
 
 otroAtributoInt: 6 
 otroAtributoFloat: 9 
 
 atributoInt: 5 
 atributoFloat: 6 
 objetoPublico: otroAtributoInt: 6 
 otroAtributoFloat: 9 
 
 objetoPrivado: otroAtributoInt: 6 
 otroAtributoFloat: 9 
 
 objetoProtegido: otroAtributoInt: 6 
 otroAtributoFloat: 9 
 Presione una tecla para continuar . . . 
 
Se aprecia en la ejecución del programa que todos los objetos que fueron declarados como atributos 
fueron inicializados correctamente mediante la lista de inicialización. 
6. INICIALIZACIÓN DE MIEMBROS DE CLASE 
Existen elementos que pueden ser declarados como miembros de una clase para los cuales la 
inicialización es esencial pero no se puede llevar a cabo este proceso mediante la asignación. Tales 
como objetos miembro de clases sin constructor por defecto, miembros constates y referencias 
miembro. 
 
 //Código 3.09: inicializacionObjetosMiembro.cpp 
 //Demostración de la inicialización de objetos miembro de clase 
 
 class unaClase 
 { 
 public: 
 unaClase(int arg1, otraClase &objeto ): atributoConstanteInt(arg1), 
 objetoMiembro(objeto), referenciaObjetoMiembro(objetoMiembro) 
 { 
 unAtributoInt = arg1; 
 } 
 void mostrar() 
 { 
 cout << "atributoConstanteInt:" << atributoConstanteInt << endl; 
 cout << "unAtributoInt: " << unAtributoInt << endl; 
 cout << "objetoMiembro: " << objetoMiembro << endl; 
 cout << "referenciaObjetoMiembro: " << referenciaObjetoMiembro << endl; 
 } 
 private: 
 int const atributoConstanteInt; 
 int unAtributoInt; 
 otraClase objetoMiembro; 
 otraClase &referenciaObjetoMiembro; 
 }; 
 
 int main() 
 { 
Laboratorio de Programación II Página 65 
 
Mgter. Ángel Montesinos Sesión N° 03 
 otraClase objOtraClase; 
 objOtraClase.setOtroAtributoInt(32); 
 unaClase objetoUnaClase(3, objOtraClase); 
 objOtraClase.mostrar(); 
 objetoUnaClase.mostrar(); 
 system("pause"); 
 return 0; 
 } 
 ostream& operator << (ostream &salida, otraClase& objeto) 
 { 
 salida << "otroAtributoInt: " << objeto.otroAtributoInt << endl; 
 return salida; 
 } 
 
No existe otra forma de inicializar los miembros tratados en el punto anterior y sería un error no 
poder hacer la inicialización adecuada de los mismos, en la mayoría de los casos para todos los 
demás tipos el programador dispone de dos formas de hacer dicha inicialización, la primera 
mediante la asignación directa de valores a los atributos y la segunda mediante el empleo de una 
lista de inicialización, suele resultar más expresivo y eficiente el segundo recurso. Por ejemplo, en 
el código anterior se puede observar que el atributo unAtributoInt fue inicializado por la asignación 
directa del parámetro arg1, en cambio los demás atributos fueron inicializados mediante la lista de 
inicialización. 
A. INICIALIZACIÓN DE MIEMBROS CONSTANTES 
La inicialización de miembros constantes estáticos integrales, es decir enteros, booleanos y 
caracteres; es posible mediante la utilización de una expresión de inicialización de constantes en la 
declaración del referido miembro de clase: 
 
 //Código 3.10: inicializacionMiembrosConstantes.cpp 
 //Demostración de la inicialización de miembro de clase constantes 
 
 #include <iostream> 
 using namespace std; 
 class otraClase 
 { 
 public: 
 int getOtroAtributoInt() 
 { 
 return otroAtributoInt; 
 } 
 void setOtroAtributoInt(int i) 
 { 
 otroAtributoInt = i; 
 } 
 void mostrar() 
 { 
 cout << "otroAtributoInt: " << otroAtributoInt << endl; 
 cout << "atributoEstaticoConstanteInt: " 
 << atributoEstaticoConstanteInt << endl; 
 } 
 friend ostream& operator << (ostream &salida, otraClase& objeto); 
 private: 
 static const int atributoEstaticoConstanteInt = 5; 
 //static const float atributoconstanteFloat = 3; //error no es integral 
 //static int atributoEstaticoInt = 2; //error no es constante 
 //const int atributoConstanteInt = 1; //error no es estático 
 //static const int otroAtributoEstaticoConstanteInt = 
 // getOtroAtributoInt(); 
 int otroAtributoInt; 
 }; 
 int main() 
 { 
 otraClase objOtraClase; 
 objOtraClase.setOtroAtributoInt(32); 
Laboratorio de Programación II Página 66 
 
Mgter. Ángel Montesinos Sesión N° 03 
 
 objOtraClase.mostrar(); 
 
 system("pause"); 
 return 0; 
 } 
 ostream& operator << (ostream &salida, otraClase& objeto) 
 { 
 salida << "otroAtributoInt: " << objeto.otroAtributoInt << endl; 
 return salida; 
 } 
 
Otra forma alternativa de poder asignar valores a constates es crer una enumeración con enum de 
constates simbólica dentro de la declaración de la clase: 
 
 //Código 3.11: inicializacionMiembrosConstantesimbolicas.cpp 
 //Demostración de inicialización de miembro de clase constantes con enum 
 
 #include <iostream> 
 using namespace std; 
 class otraClase 
 { 
 public: 
 int getOtroAtributoInt() 
 { 
 return otroAtributoInt; 
 } 
 void setOtroAtributoInt(int i) 
 { 
 otroAtributoInt = i; 
 } 
 void mostrar() 
 { 
 cout << "otroAtributoInt: " << otroAtributoInt << endl; 
 cout << "atributoEstaticoConstanteInt: " 
 << atributoEstaticoConstanteInt << endl; 
 cout << "atributoconstanteFloat: " << atributoconstanteFloat << endl; 
 cout << "atributoEstaticoInt: " << atributoEstaticoInt << endl; 
 cout << "atributoConstanteInt: " << atributoConstanteInt << endl; 
 cout << "otroAtributoEstaticoConstanteInt: " 
 << otroAtributoEstaticoConstanteInt << endl; 
 } 
 friend ostream& operator << (ostream &salida, otraClase& objeto); 
 private: 
 enum{atributoEstaticoConstanteInt = 5,atributoconstanteFloat = 2, 
 atributoEstaticoInt = 6,atributoConstanteInt = 9, 
 otroAtributoEstaticoConstanteInt =12}; 
 //static const int atributoEstaticoConstanteInt = 5; 
 //static const float atributoconstanteFloat = 2; //error no es integral 
 //static int atributoEstaticoInt = 6; //error no es constante 
 //const int atributoConstanteInt = 9; //error no es estático 
 //static const int otroAtributoEstaticoConstanteInt 
 
 int otroAtributoInt; 
 }; 
 int main() 
 { 
 otraClase objOtraClase; 
 objOtraClase.setOtroAtributoInt(32); 
 objOtraClase.mostrar(); 
 system("pause"); 
 return 0; 
 } 
 ostream& operator << (ostream &salida, otraClase& objeto) 
 { 
 salida << "otroAtributoInt: " << objeto.otroAtributoInt << endl; 
Laboratorio de Programación II Página 67 
 
Mgter. Ángel Montesinos Sesión N° 03 
 return salida; 
 } 
 
Si utilizamos esta alternativa no estaremos tentados a hacer inicializaciones dentro de la clase. 
7. RESUMEN 
Los punteros a objetos almacenan la dirección del objeto a cual apuntan, pero este mecanismo 
puede ser empleado de una manera similar con un recurso llamado referencia, el cual maneja la 
dirección del objeto o sus miembros pero por el contario actúa como un alias del recurso al cual 
hace referencia; durante la construcción de los métodos debemos muchas veces hacer mención al 
objeto que está manipulando los recursos y no existe una forma clara de hacerlo porque eso lo hará 
el mismo objeto instanciado, el puntero implícito this se refiere al objeto que está ejecutando el 
método en ese momento; las autoreferencias permuten encadenar la ejecución de métodos por un 
mismo objetos, de esta forma es más potente el envío de mensajes. 
los constructores son los recursos(métodos) encargados de hacer que un objeto aparezca de forma 
adecuada en un programa, sin ellos los objetos pueden ser construidos de forma errónea, los 
compiladores manejan constructores por defecto. Los destructores son el método inverso al 
constructor, mientras los constructores crean adecuadamente a un objeto un destructor elimina 
adecuadamente a un objeto y recupera de forma adecuada los recursos asignados a dicho objeto, 
como por ejemplo la memoria, los constructores y destructores tienen el mismo nombre de la clase, 
ambos se invocan implícitamente, los primeros al ser creado un objeto y los segundos al dejar de 
tener sentido el objeto en el contexto donde funcionaba. La diferencia entre un constructor y un 
destructor es el carácter virgulilla(~), que significa la negación 
IV 
EXPERIENCIAS DE PRACTICA 
1. Constructores y destructores: 
Crear los respectivos métodos constructores y destructores para cada clase modelando 
adecuadamente la inicialización de cada objeto de clase y su desaparición en la operación del 
programa. 
2. Objetos como atributosde clase: 
Agregar a objetos como atributos de clase modelando adecuadamente los constructores y 
destructores así como los métodos que estarán involucrados en su operación y procesamiento. 
V 
 EJERCICIOS 
1. Elaborar un mapa de los mensajes de los métodos. 
2. Agregar un menú de opciones al programa. 
VI 
 CUESTIONARIO 
1. ¿Qué es un puntero? 
2. ¿Qué es una referencia? 
3. ¿Qué es una autoreferencia? 
4. ¿Cómo se usan las referencias a objetos? 
5. ¿Por qué tenemos que usar referencias? 
6. ¿Por qué tenemos que usar auto referencias?7. ¿Qué es el puntero implícito this? 
8. ¿Cómo se usa el puntero implícito this? 
9. ¿Por qué tenemos que usar el puntero implícito this? 
10. ¿Cuáles son los tipos de clases de almacenamiento? 
11. ¿Cuál es la forma como se representa una clase en UML? 
12. ¿Cómo se representa los miembros públicos en un diagrama de clases? 
13. ¿Cómo se representa los miembros privados en un diagrama de clases? 
Laboratorio de Programación II Página 68 
 
Mgter. Ángel Montesinos Sesión N° 03 
14. ¿Cómo se representa los miembros protegidos en un diagrama de clases? 
15. ¿Cómo se representa una relación binaria en un diagrama de clases? 
16. ¿Cómo se representa una relación reflexiva en un diagrama de clases? 
17. ¿Cómo se representa una relación n-aria en un diagrama de clases? 
18. ¿Cómo se representa una relación de agregación en un diagrama de clases? 
19. ¿Cómo se representa una relación de composición en un diagrama de clases? 
20. ¿Cómo se representa una relación de dependencia en un diagrama de clases? 
21. ¿Cómo se representa una relación de herencia en un diagrama de clases? 
VII 
 BIBLIOGRAFIA Y REFERENCIAS 
• Deitel, Paul J., Deitel, Harvey M., "Cómo Programar en C++", 6ta Edición, Ed. Pearson Educación, 
México 2009. 
• Stroustrup, Bjarne, "El Lenguaje de Programación C++", 3ra Edición, Adisson Pearson Educación S.A., 
Madrid 2002. 
• Eckel, Bruce, "Thinking in C++", 2da Edición, Prentice Hall, 2000.

Continuar navegando

Otros materiales