13.01.2015 Views

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

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

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

SHOW MORE
SHOW LESS

Create successful ePaper yourself

Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.

✐<br />

✐<br />

✐<br />

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

✐<br />

Capítulo 14. Her<strong>en</strong>cia y Composición<br />

si se hubiese creado un objeto X d<strong>en</strong>tro de la clase Y <strong>en</strong> vez de heredar de X. Tanto<br />

los miembros objetos y la clase base son conocidos como subobjetos.<br />

Todos los elem<strong>en</strong>tos privados de X continúan si<strong>en</strong>do privados <strong>en</strong> Y; esto es, aunque<br />

Y hereda de X no significa que Y pueda romper el mecanismo de protección. Los<br />

elem<strong>en</strong>tos privados de X continúan existi<strong>en</strong>do, ocupando su espacio - sólo que no se<br />

puede acceder a ellos directam<strong>en</strong>te.<br />

En main() observamos que los datos de Y están combinados con los datos de X<br />

porque sizeof(Y) es el doble de grande que el sizeof(X).<br />

Observará que la clase base es precedida por public. Durante la her<strong>en</strong>cia, por defecto,<br />

todo es privado. Si la clase base no estuviese precedida por public, significaría<br />

que todos los miembros públicos de la clase base serían privados <strong>en</strong> la clase derivada.<br />

Esto, <strong>en</strong> la mayoría de ocasiones no es lo deseado [51]; el resultado que se desea<br />

es mant<strong>en</strong>er todos los miembros públicos de la clase base <strong>en</strong> la clase derivada. Para<br />

hacer esto, se usa la palabra clave public durante la her<strong>en</strong>cia.<br />

En change(), se utiliza a la función de la clase base permute(). La clase derivada<br />

ti<strong>en</strong>e acceso directo a todas las funciones públicas de la clase base.<br />

La función set() <strong>en</strong> la clase derivada redefine la función set() de la clase base. Esto<br />

es, si llama a las funciones read() y permute() de un objeto Y, conseguirá las versiones<br />

de la clase base (esto es lo que esta ocurri<strong>en</strong>do d<strong>en</strong>tro de main()). Pero si llamamos<br />

a set() <strong>en</strong> un objeto Y, conseguiremos la versión redefinida. Esto significa que si no<br />

deseamos un comportami<strong>en</strong>to de una función durante la her<strong>en</strong>cia, se puede cambiar.<br />

(También se pued<strong>en</strong> añadir funciones completam<strong>en</strong>te nuevas como change().)<br />

Sin embargo, cuando redefinimos una función, puede ser que desee llamar a la<br />

versión de la clase base. Si, d<strong>en</strong>tro de set(), simplem<strong>en</strong>te llama a set(), conseguiremos<br />

una versión local de la función - una función recursiva. Para llamar a la versión de<br />

la clase base, se debe explícitam<strong>en</strong>te utilizar el nombre de la clase base y el operador<br />

de resolución de alcance.<br />

14.3. Lista de inicializadores de un constructor<br />

Hemos visto lo importante que es <strong>en</strong> <strong>C++</strong> garantizar una correcta inicialización,<br />

y esto no va a cambiar <strong>en</strong> la composición ni <strong>en</strong> la her<strong>en</strong>cia. Cuando se crea un objeto,<br />

el compilador garantiza la ejecución todos los constructores para cada uno de los<br />

subobjetos. Hasta ahora, <strong>en</strong> los ejemplos, todos los subobjetos ti<strong>en</strong><strong>en</strong> un constructor<br />

por defecto, que es ejecutado por el compilador automáticam<strong>en</strong>te. Pero que ocurre si<br />

uno de nuestros subobjetos no ti<strong>en</strong>e constructores por defecto, o si queremos cambiar<br />

los parámetros por defecto de un constructor. Esto supone un problema, porque el<br />

constructor de la nueva clase no ti<strong>en</strong>e permiso para acceder a los miembros privados<br />

del subobjeto y por ello, no puede inicializarlos directam<strong>en</strong>te.<br />

La solución es simple: ejecutar el constructor del subobjeto. <strong>C++</strong> proporciona una<br />

sintaxis especial para ello, la lista de inicializadores de un constructor. La forma de<br />

la lista de inicializadores de un constructor demuestra como actúa como la her<strong>en</strong>cia.<br />

Con la her<strong>en</strong>cia, las clases bases son colocadas después de dos puntos y justo<br />

después, puede abrir la llave para empezar con el cuerpo de la clase. En la lista de<br />

inicializadores de un constructor, se coloca las llamadas a los constructores de los<br />

subobjetos, después los argum<strong>en</strong>tos del constructor y los dos puntos, pero todo esto,<br />

antes de abrir el brazo del cuerpo de la función. En una clase MyType, que hereda<br />

de Bar, sería de la sigui<strong>en</strong>te manera:<br />

406<br />

✐<br />

✐<br />

✐<br />

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

Saved successfully!

Ooh no, something went wrong!