Pensar en C++ (Volumen 1) - Grupo ARCO
Pensar en C++ (Volumen 1) - Grupo ARCO
Pensar en C++ (Volumen 1) - Grupo ARCO
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 />
✐