Pensar en C++ (Volumen 1) - Grupo ARCO

Pensar en C++ (Volumen 1) - Grupo ARCO Pensar en C++ (Volumen 1) - Grupo ARCO

arco.esi.uclm.es
from arco.esi.uclm.es More from this publisher
13.01.2015 Views

✐ ✐ ✐ “Volumen1” — 2012/1/12 — 13:52 — page 186 — #224 ✐ Capítulo 5. Ocultar la implementación 4. Escriba dos clases, cada una de ellas con un método que reciba como argumento un puntero a un objeto de la otra clase. Cree instancias de ambas clases en main() y llame a los métodos antes mencionados de cada clase. 5. Cree tres clases. La primera contiene miembros privados, y declara como friend a toda la segunda estructura y a una función miembro de la tercera. En main() demuestre que todo esto funciona correctamente. 6. Cree una clase Hen. Dentro de ésta, inserte una clase Nest. Y dentro de ésta una clase Egg. Cada clase debe tener un método display(). En main(), cree una instancia de cada clase y llame a la función display() de cada una. 7. Modifique el ejercicio 6 para que Nest y Egg contengan datos privados. De acceso mediante friend para que las clases puedan acceder a los contenidos privados de las clases que contienen. 8. Cree una clase con atributos diseminados por numerosas secciones public, private y protected. Añada el método ShowMap() que imprima por pantalla los nombres de cada uno de esos atributos y su dirección de memoria. Si es posible, compile y ejecute este programa con más de un compilador y/o ordenador y/o sistema operativo para ver si existen diferencias en las posiciones en memoria. 9. Copie la implementación y ficheros de prueba de Stash del capítulo 4 para así poder compilar y probar el Stash.h de este capítulo. 10. Ponga objetos de la clase Hern definidos en el ejercicio 6 en un Stash. Apunte a ellos e imprímalos (si no lo ha hecho aún necesitará una función Hen::print()). 11. Copie los ficheros de implementación y la prueba de Stack del capítulo 4 y compile y pruebe el Stack2.h de este capítulo. 12. Ponga objetos de la clase Hen del ejercicio 6 dentro de Stack. Apunte a ellos e imprímalos (si no lo ha hecho aún, necesitara añadir un Hen::print()). 13. Modifique Chesire en Handle.cpp, y verifique que su entorno de desarrollo recompila y reemplaza sólo este fichero, pero no recompila UseHandle.cpp. 14. Cree una clase StackOfInt (una pila que guarda enteros) usando la técnica «Gato de Chesire» que esconda la estructura de datos de bajo nivel que usa para guardar los elementos, en una clase llamada StackImp. Implemente dos versiones de StackImp: una que use un array de longitud fija de enteros, y otra que use un vector. Ponga un tamaño máximo para la pila preestablecido, así no se tendrá que preocupar de expandir el array en la primera versión. Fíjese que la clase StackOfInt.h no tiene que cambiar con Stack- Imp. 186 ✐ ✐ ✐ ✐

✐ ✐ ✐ “Volumen1” — 2012/1/12 — 13:52 — page 187 — #225 ✐ 6: Inicialización y limpieza El capitulo 4 constituye una mejora significativa en el uso de librerías tomando los diversos componentes de una librería C típica y encapsulándolos en una estructura (un tipo abstracto de dato, llamado clase a partir de ahora). Esto no sólo permite disponer de un único punto de entrada en un componente de librería, también oculta los nombres de las funciones con el nombre de la clase. Esto le da al diseñador de la clase la posibilidad de establecer límites claros que determinan qué cosas puede hacer el programador cliente y qué queda fuera de sus límites. Eso significa que los mecanismos internos de las operaciones sobre los tipos de datos están bajo el control y la discreción del diseñador de la clase, y deja claro a qué miembros puede y debe prestar atención el programador cliente. Juntos, la encapsulación y el control de acceso representan un paso significativo para aumentar la sencillez de uso de las librerías. El concepto de «nuevo tipo de dato» que ofrecen es mejor en algunos sentidos que los tipos de datos que incorpora C. El compilador C++ ahora puede ofrecer garantías de comprobación de tipos para esos tipos de datos y así asegura un nivel de seguridad cuando se usan esos tipos de datos. A parte de la seguridad, el compilador puede hacer mucho más por nosotros de lo que ofrece C. En éste y en próximos capítulos verá posibilidades adicionales que se han incluido en C++ y que hacen que los errores en sus programas casi salten del programa y le agarren, a veces antes incluso de compilar el programa, pero normalmente en forma de advertencias y errores en el proceso de compilación. Por este motivo, pronto se acostumbrará a la extraña situación en que un programa C++ que compila, funciona a la primera. Dos de esas cuestiones de seguridad son la inicialización y la limpieza. Gran parte de los errores de C se deben a que el programador olvida inicializar o liberar una variable. Esto sucede especialmente con las librerías C, cuando el programador cliente no sabe como inicializar una estructura, o incluso si debe hacerlo. (A menudo las librerías no incluyen una función de inicialización, de modo que el programador cliente se ve forzado a inicializar la estructura a mano). La limpieza es un problema especial porque los programadores C se olvidan de las variables una vez que han terminado, de modo que omiten cualquier limpieza que pudiera ser necesaria en alguna estructura de la librería. En C++. el concepto de inicialización y limpieza es esencial para facilitar el uso de las librerías y eliminar muchos de los errores sutiles que ocurren cuando el programador cliente olvida cumplir con sus actividades. Este capítulo examina las posibilidades de C++ que ayudan a garantizar una inicialización y limpieza apropiadas. 187 ✐ ✐ ✐ ✐

✐<br />

✐<br />

✐<br />

“Volum<strong>en</strong>1” — 2012/1/12 — 13:52 — page 187 — #225<br />

✐<br />

6: Inicialización y limpieza<br />

El capitulo 4 constituye una mejora significativa <strong>en</strong> el uso de librerías<br />

tomando los diversos compon<strong>en</strong>tes de una librería C típica y<br />

<strong>en</strong>capsulándolos <strong>en</strong> una estructura (un tipo abstracto de dato, llamado<br />

clase a partir de ahora).<br />

Esto no sólo permite disponer de un único punto de <strong>en</strong>trada <strong>en</strong> un compon<strong>en</strong>te<br />

de librería, también oculta los nombres de las funciones con el nombre de la clase.<br />

Esto le da al diseñador de la clase la posibilidad de establecer límites claros que<br />

determinan qué cosas puede hacer el programador cli<strong>en</strong>te y qué queda fuera de sus<br />

límites. Eso significa que los mecanismos internos de las operaciones sobre los tipos<br />

de datos están bajo el control y la discreción del diseñador de la clase, y deja claro a<br />

qué miembros puede y debe prestar at<strong>en</strong>ción el programador cli<strong>en</strong>te.<br />

Juntos, la <strong>en</strong>capsulación y el control de acceso repres<strong>en</strong>tan un paso significativo<br />

para aum<strong>en</strong>tar la s<strong>en</strong>cillez de uso de las librerías. El concepto de «nuevo tipo de<br />

dato» que ofrec<strong>en</strong> es mejor <strong>en</strong> algunos s<strong>en</strong>tidos que los tipos de datos que incorpora<br />

C. El compilador <strong>C++</strong> ahora puede ofrecer garantías de comprobación de tipos para<br />

esos tipos de datos y así asegura un nivel de seguridad cuando se usan esos tipos de<br />

datos.<br />

A parte de la seguridad, el compilador puede hacer mucho más por nosotros de<br />

lo que ofrece C. En éste y <strong>en</strong> próximos capítulos verá posibilidades adicionales que<br />

se han incluido <strong>en</strong> <strong>C++</strong> y que hac<strong>en</strong> que los errores <strong>en</strong> sus programas casi salt<strong>en</strong><br />

del programa y le agarr<strong>en</strong>, a veces antes incluso de compilar el programa, pero normalm<strong>en</strong>te<br />

<strong>en</strong> forma de advert<strong>en</strong>cias y errores <strong>en</strong> el proceso de compilación. Por este<br />

motivo, pronto se acostumbrará a la extraña situación <strong>en</strong> que un programa <strong>C++</strong> que<br />

compila, funciona a la primera.<br />

Dos de esas cuestiones de seguridad son la inicialización y la limpieza. Gran parte<br />

de los errores de C se deb<strong>en</strong> a que el programador olvida inicializar o liberar<br />

una variable. Esto sucede especialm<strong>en</strong>te con las librerías C, cuando el programador<br />

cli<strong>en</strong>te no sabe como inicializar una estructura, o incluso si debe hacerlo. (A m<strong>en</strong>udo<br />

las librerías no incluy<strong>en</strong> una función de inicialización, de modo que el programador<br />

cli<strong>en</strong>te se ve forzado a inicializar la estructura a mano). La limpieza es un problema<br />

especial porque los programadores C se olvidan de las variables una vez que han<br />

terminado, de modo que omit<strong>en</strong> cualquier limpieza que pudiera ser necesaria <strong>en</strong><br />

alguna estructura de la librería.<br />

En <strong>C++</strong>. el concepto de inicialización y limpieza es es<strong>en</strong>cial para facilitar el uso<br />

de las librerías y eliminar muchos de los errores sutiles que ocurr<strong>en</strong> cuando el programador<br />

cli<strong>en</strong>te olvida cumplir con sus actividades. Este capítulo examina las posibilidades<br />

de <strong>C++</strong> que ayudan a garantizar una inicialización y limpieza apropiadas.<br />

187<br />

✐<br />

✐<br />

✐<br />

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!