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 322 — #360<br />

✐<br />

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

m<strong>en</strong>te, y la salida del programa revela la manera <strong>en</strong> que se crea:<br />

Cont<strong>en</strong>ts of c: Composite()<br />

Calling Composite copy-constructor<br />

WithCC(WithCC&)<br />

Cont<strong>en</strong>ts of c2: Composite()<br />

Para la creación de un constructor de copia para una clase que utiliza composición<br />

(y her<strong>en</strong>cia, que se trata <strong>en</strong> el Capítulo 14), el compilador llama a todos los<br />

constructores de copia de todos los miembros objeto y de las clases base de manera<br />

recursiva. Es decir, si el miembro también conti<strong>en</strong>e otro objeto, también se llama a<br />

su constructor de copia. En el ejemplo, el compilador llama al constructor de copia<br />

de WithCC. La salida muestra que se llama a este constructor. Como WoCC no ti<strong>en</strong>e<br />

constructor de copia, el compilador crea uno que realiza simplem<strong>en</strong>te una copia bit a<br />

bit para que el constructor de copia de Composite lo pueda llamar. La llamada a C-<br />

omposite::print() <strong>en</strong> main() muestra que esto ocurre, porque el cont<strong>en</strong>ido de<br />

c2.wocc es idéntico al cont<strong>en</strong>ido de c.wocc. El proceso que realiza el compilador<br />

para crear un constructor de copia se d<strong>en</strong>omina inicialización de miembros (memberwise<br />

initialization).<br />

Se recomi<strong>en</strong>da definir constructor de copia propio <strong>en</strong> vez de usar el que crea el<br />

compilador. Eso garantiza que estará bajo su control.<br />

11.3.4. Alternativas a la construcción por copia<br />

A estas alturas su cabeza debe estar echando humo, y se preguntará cómo es<br />

posible que pudiera escribir una clase que funcionase sin saber nada acerca del constructor<br />

de copia. No obstante, recuerde que el constructor de copia sólo es necesario<br />

cuando la clase se pasa por valor. Si esto no va a ocurrir, <strong>en</strong>tonces no lo necesita.<br />

Evitando el paso por valor<br />

«Pero», puede decir, «si no defino el constructor de copia, el compilador lo creará<br />

por mí. ¿Cómo sé que un objeto nunca se pasará por valor»<br />

Existe una técnica simple para evitar el paso por valor: declare un constructor de<br />

copia private. Ni siquiera necesita definirlo (sólo declararlo), a no ser que un método<br />

o una función fri<strong>en</strong>d necesite realizar un paso por valor. Si el usuario int<strong>en</strong>ta<br />

pasar o retornar el objeto por valor, el compilador se quejará con un error porque el<br />

constructor de copia es privado. El compilador ya no puede crear un constructor de<br />

copia por defecto porque explícitam<strong>en</strong>te ya hay uno creado.<br />

He aquí un ejemplo:<br />

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

// Prev<strong>en</strong>ting copy-construction<br />

class NoCC {<br />

int i;<br />

NoCC(const NoCC&); // No definition<br />

public:<br />

NoCC(int ii = 0) : i(ii) {}<br />

};<br />

void f(NoCC);<br />

322<br />

✐<br />

✐<br />

✐<br />

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

Saved successfully!

Ooh no, something went wrong!