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

You also want an ePaper? Increase the reach of your titles

YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.

✐<br />

✐<br />

✐<br />

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

✐<br />

Capítulo 11. Las refer<strong>en</strong>cias y el constructor de copia<br />

producirse por un ev<strong>en</strong>to hardware, y no con una invocación d<strong>en</strong>tro del programa<br />

de forma explícita).<br />

Ahora imagine que pasaría si una función normal int<strong>en</strong>tara retornar valores mediante<br />

la pila. No puede tocar la pila por <strong>en</strong>cima del la dirección de retorno, así que<br />

la función t<strong>en</strong>dría que colocar los valores de retorno debajo de la dirección de retorno.<br />

Pero cuando se ejecuta el RETURN, el puntero de pila debería estar apuntando<br />

a la dirección de retorno (o justo debajo, dep<strong>en</strong>de de la máquina), así que la función<br />

debe subir el puntero de la pila, desechando todas las variables locales. Si int<strong>en</strong>ta retornar<br />

valores usando la pila por debajo de la dirección de retorno, <strong>en</strong> ese mom<strong>en</strong>to<br />

es vulnerable a una interrupción. La ISR escribiría <strong>en</strong>cima de los valores de retorno<br />

para colocar su dirección de retorno y sus variables locales.<br />

Para resolver este problema, el que llama a la función podría hacerse responsable<br />

de asignar la memoria extra <strong>en</strong> la pila para los valores de retorno antes de llamar a<br />

la función. Sin embargo, C no se diseñó de esta manera y <strong>C++</strong> ha de ser compatible.<br />

Como verá pronto, el compilador de <strong>C++</strong> utiliza un esquema más eficaz.<br />

Otra idea sería retornar el valor utilizando un área de datos global, pero tampoco<br />

funcionaría. La re-<strong>en</strong>trada significa que cualquier función puede ser una rutina de<br />

interrupción para otra función, incluida la función que se está ejecutando. Por lo tanto, si<br />

coloca un valor de retorno <strong>en</strong> un área global, podría retornar a la misma función, lo<br />

cual sobreescribiría el valor de retorno. La misma lógica se aplica a la recursividad.<br />

Los registros son el único lugar seguro para devolver valores, así que se vuelve al<br />

problema de qué hacer cuando los registros no son lo sufici<strong>en</strong>tem<strong>en</strong>te grandes para<br />

cont<strong>en</strong>er el valor de retorno. La respuesta es colocar la dirección de la ubicación del<br />

valor de retorno <strong>en</strong> la pila como uno de los argum<strong>en</strong>tos de la función, y dejar que la<br />

función copie la información que se devuelve directam<strong>en</strong>te <strong>en</strong> esa ubicación. Esto no<br />

solo soluciona todo los problemas, si no que además es más eficaz. Ésta es la razón<br />

por la que el compilador coloca la dirección de B2 antes de llamar a bigfun <strong>en</strong> la<br />

función main() de PassingBigStructures.cpp. Si viera el código <strong>en</strong>samblador<br />

de bigfun() observaría que la función espera este argum<strong>en</strong>to escondido y lo copia<br />

al destino d<strong>en</strong>tro de la función.<br />

Copia bit a bit vs. inicialización<br />

Hasta aquí, todo bi<strong>en</strong>. T<strong>en</strong>emos un procedimi<strong>en</strong>to para pasar y retornar estructuras<br />

simples grandes. Pero note que lo único que ti<strong>en</strong>e es una manera de copiar bits<br />

de un lugar a otro, lo que ciertam<strong>en</strong>te funciona bi<strong>en</strong> para la forma (muy primitiva)<br />

<strong>en</strong> que C trata las variables. Sin embargo, <strong>en</strong> <strong>C++</strong> los objetos pued<strong>en</strong> ser mucho más<br />

avanzados que un puñado de bits, pues ti<strong>en</strong><strong>en</strong> significado y, por lo tanto, puede que<br />

no responda bi<strong>en</strong> al ser copiado.<br />

Considere un ejemplo simple: una clase que conoce cuantos objetos de un tipo<br />

exist<strong>en</strong> <strong>en</strong> cualquier mom<strong>en</strong>to. En el Capítulo 10 se vio la manera de hacerlo incluy<strong>en</strong>do<br />

un atributo estático (static):<br />

//: C11:HowMany.cpp<br />

// A class that counts its objects<br />

#include <br />

#include <br />

using namespace std;<br />

ofstream out("HowMany.out");<br />

class HowMany {<br />

static int objectCount;<br />

314<br />

✐<br />

✐<br />

✐<br />

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

Saved successfully!

Ooh no, something went wrong!