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 311 — #349<br />

✐<br />

11.3. El constructor de copia<br />

Al ejecutar este programa se observa que el puntero se increm<strong>en</strong>ta <strong>en</strong> vez de<br />

increm<strong>en</strong>tar a lo que apunta.<br />

11.2.2. Consejos para el paso de argum<strong>en</strong>tos<br />

Cuando se pasa un argum<strong>en</strong>to a un función, lo normal debería ser pasarlo como<br />

una refer<strong>en</strong>cia constante. Aunque al principio puede parecer que sólo ti<strong>en</strong>e v<strong>en</strong>tajas<br />

<strong>en</strong> términos de eficacia (y normalm<strong>en</strong>te <strong>en</strong> diseño e implem<strong>en</strong>tación inicial no se<br />

ti<strong>en</strong>e muy <strong>en</strong> cu<strong>en</strong>ta la eficacia), además ti<strong>en</strong>e otras: como se podrá ver <strong>en</strong> el resto<br />

del capítulo, se requiere un constructor de copia para pasar un objeto por valor, y<br />

esto no siempre es posible.<br />

La eficacia puede mejorar substancialm<strong>en</strong>te por este simple hábito: pasar un argum<strong>en</strong>to<br />

por valor necesita una llamada a un constructor y otra a un destructor,<br />

pero si no se va a modificar el argum<strong>en</strong>to, el hecho de pasarlo como una refer<strong>en</strong>cia<br />

constante sólo necesita poner una dirección <strong>en</strong> la pila.<br />

De hecho, prácticam<strong>en</strong>te la única situación <strong>en</strong> la que no es preferible pasar la<br />

dirección, es cuando provocará tales problemas a un objeto que pasar por valor es la<br />

única alternativa segura (<strong>en</strong> vez de modificar el objeto que está fuera del ámbito de<br />

la función, algo que el que llama a la función normalm<strong>en</strong>te no espera). Ese es el tema<br />

de la sigui<strong>en</strong>te sección.<br />

11.3. El constructor de copia<br />

Ahora que <strong>en</strong>ti<strong>en</strong>de lo básico de las refer<strong>en</strong>cias <strong>en</strong> <strong>C++</strong>, está preparado para tratar<br />

uno de los conceptos más confusos del l<strong>en</strong>guaje: el constructor de copia, a m<strong>en</strong>udo<br />

d<strong>en</strong>ominado X(X&) («X de la refer<strong>en</strong>cia X»). Este constructor es es<strong>en</strong>cial para controlar<br />

el paso y retorno por valor de los tipos definidos por el usuario <strong>en</strong> las llamadas<br />

a funciones. De hecho es tan importante que el compilador crea automáticam<strong>en</strong>te un<br />

constructor de copia <strong>en</strong> caso de que el programador no lo proporcione.<br />

11.3.1. Paso y retorno por valor<br />

Para <strong>en</strong>t<strong>en</strong>der la necesidad del constructor de copia, considere la forma <strong>en</strong> que<br />

C maneja el paso y retorno por valor de variables cuando se llama a una función. Si<br />

declara una función y la invoca,<br />

int f(int x, char c);<br />

int g = f(a, b);<br />

¿cómo sabe el compilador cómo pasar y retornar esas variables ¡Simplem<strong>en</strong>te lo<br />

sabe! El rango de tipos con los que debe tratar es tan pequeño (char, int, float, double,<br />

y sus variaciones), que tal información ya está d<strong>en</strong>tro del compilador.<br />

Si averigua cómo hacer que su compilador g<strong>en</strong>ere código <strong>en</strong>samblador y determina<br />

qué instrucciones se usan para la invocación de la función f(), obt<strong>en</strong>drá algo<br />

equival<strong>en</strong>te a:<br />

push<br />

b<br />

311<br />

✐<br />

✐<br />

✐<br />

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

Saved successfully!

Ooh no, something went wrong!