<div dir="ltr">Super bien entendido gracias , como siempre.<div><br></div><div style>Ahora , y de verdad que pena molestar tanto pero es que de verdad hay algunos ejercicios que no logro comprender.</div><div style><br></div>
<div style>El siguiente programa:</div><div style><br></div><div style><div>class A</div><div>{</div><div>public:</div><div>    A(int n = 2) : m_i(n) { }</div><div><br></div><div>    ~A() { std::cout << m_i; }</div>
<div><br></div><div>protected:</div><div>    int m_i;</div><div>};</div><div><br></div><div>class B</div><div>    : public A</div><div>{</div><div>public:</div><div>    B(int n) : m_x(m_i + 1) , m_a(n) { }</div><div><br></div>
<div>public:</div><div>    ~B()</div><div>    {</div><div><span class="" style="white-space:pre">           </span>std::cout << m_i;</div><div><span class="" style="white-space:pre">            </span>--m_i;</div><div>        </div><div>
    }</div><div><br></div><div>private:</div><div>    A m_x;</div><div>    A m_a;</div><div>};</div><div><br></div><div>int main()</div><div>{</div><div>    { B b(5); }</div><div><br></div><div>    std::cout << std::endl;</div>
<div><span class="" style="white-space:pre">    </span>getchar();</div><div>    return 0;</div><div>}</div><div><br></div><div style>Lo comilo y al ejecutarlo me da como resultado 2531. Ahora bien el 2 , entiendo bien de donde viene. es la inicializacion implicita que se hace desde la clase derivada , pero el 5 ,no lo entiendo si en el destructor utilizamos es m_i del constructor , entonces no seria el 1?, y los otros dos numeros no entiendo bien como los imprime el programa.</div>
<div style><br></div><div style><br></div><div style>Gracias por la ayuda que sera bien recibida.</div><div style><br></div><div style>Cordialmente</div></div></div><div class="gmail_extra"><br><br><div class="gmail_quote">
2013/5/20 Salvador Pozo <span dir="ltr"><<a href="mailto:salvador@conclase.net" target="_blank">salvador@conclase.net</a>></span><br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
Hola:<br>
<br>
MAj> ya probado este codigo , el resultado es:<br>
MAj> 2<br>
MAj> 0<br>
MAj> pero no lo tengo claro , es decir personalmente pensaria que , son compilar<br>
MAj> y son probar el codigo al ejecutarlo tendria una respuesta como:<br>
MAj> 1<br>
MAj> 2<br>
MAj> Primero no entiendo como funciona si estoy enviando como parametro un<br>
MAj> numero entero<br>
<br>
Empecemos por el principio, pues:<br>
<br>
Estás pasando como parámetro un entero, pero la función "f" espera una o dos referencias a objetos de la clase A, por lo tanto, hace una conversión implícita de int a A, y usa el valor por defecto para el segundo parámetro.<br>

<br>
En estos casos, los constructores con un parámetro de un tipo cualquiera de las clases se pueden (y generalmente así se hace) considerar como operadores de conversión de tipo.<br>
<br>
Por ejemplo, un constructor de una clase X que admita un entero, se puede considerar como un operador de conversión de tipo de entero a X. Otro constructor con un parámetro de tipo float, se considera un operador de conversión de tipo de float a X, etc.<br>

<br>
De forma simétrica, un operador que devuelva un entero se puede considerar un operador de conversión de tipo de X a int, pero en ese caso, C++ permite difinir el operador directamente. En tu clase, por ejemplo, podemos definir el operador de conversión de tipo a int de este modo:<br>

<br>
operator int() { return mn; }<br>
<br>
Y usarlo de este modo:<br>
<br>
cout << (int)a << endl;<br>
<br>
Observa que no necesitamos indicar el valor de retorno. El operador int siempre devuelve un valor int.<br>
<br>
MAj> Tambien , creeria que el unico que implicitamente funciona es el<br>
MAj> constructor copia por que como parametros recibimos : const A &a2 = A()<br>
MAj> Es decir este parametro hace que se ingrese al constructor declarado , peor<br>
MAj> el otro no se como relacionarlo con un entero.<br>
<br>
Te estás equivocando con el operador &. Cuando se usa en una declaración de parámetro dentro de una función, le estás diciendo al compilador que lo que estás pasando es una referencia al objeto. Esto no es lo mismo que hacer una copia por referencia. De hecho, es todo lo contrario, estás impidiendo que se haga una copia del objeto.<br>

<br>
En este caso:<br>
void f(const A &a1 , const A &a2= A())...<br>
<br>
a1 es una referencia, o lo que es lo mismo, un alias para el objeto que has pasado como primer parámetro. Concretamente, es una referencia constante.<br>
<br>
a2 es otra referencia, si la llamada se hace con dos argumentos, es una referencia al segundo. Si se hace con uno sólo, es una referencia al objeto creado en ese mismo momento.<br>
<br>
Ahora veamos por qué la salida es 2 y 0.<br>
<br>
Evidentemente, es porque se invoca dos veces al constructor con un entero como entrada, y ninguna al constructor copia.<br>
<br>
Las dos llamadas al constructor están hechas en la invocación a la función "f", una por cada parámetro.<br>
<br>
En el primer parámetro, como llamamos con un entero, se hace una conversión de tipo, de int a A. O si lo prefieres, llamamos al constructor que requiere como parámetro un entero, ya que es el único disponible.<br>
<br>
En el segundo parámetro, como no se proporciona un valor, se crea un parámetro con valor por defecto, y se invoca al constructor con un parámetro entero, usando el valor por defecto, que es cero.<br>
<br>
El constructor copia se puede invocar explícitamente, haciendo una copia de un objeto existente.<br>
<br>
Por ejemplo:<br>
<br>
    A a(19);<br>
    A b(a); // Usar el constructor copia<br>
<br>
En tu caso, como no hemos definido el operador de asignación, también podemos invocar el constructor copia usando el operador.<br>
<br>
    A c=a;  // Usar el constructor copia a través de asignación.<br>
<br>
Esto es porque el operador de asignación se define desde el constructor copia por defecto.<br>
<br>
Si quieres una función que use el operador copia en sus parámetros, pasa los parámetros por copia, y no por referencia:<br>
<br>
void f2(A a1, A a2=A()) {}<br>
<br>
    A a(4), b(9);<br>
    f2(a, b);<br>
<br>
Quiero hacer notar un hecho curioso. Si invocamos a f2 con uno o dos parámetros enteros, ¿qué crees que pasaría?<br>
<br>
    f2(3, 5);<br>
<br>
Lo lógico es que se usase el constructor con un parámetro entero para construir cada objeto argumento, y luego el constructor copia para hacer copia de esos argumentos y pasarlos a la función.<br>
<br>
Pero si lo pruebas verás que el constructor copia no se invoca en este caso.<br>
<br>
El motivo es que el compilador dispone de optimizaciones, y no siempre sigue todos los pasos previsibles según la teoría. En este caso, deduce que no necesita copiar los parámetros, ya que son parámetros por valor, y los parámetros originales son constantes, no es necesario trabajar con una copia de los objetos creados, y prescinde de esa copia.<br>

<div class="HOEnZb"><div class="h5"><br>
Hasta pronto.<br>
<br>
--<br>
Salvador Pozo (Administrador)<br>
mailto:<a href="mailto:salvador@conclase.net">salvador@conclase.net</a><br>
_______________________________________________<br>
Lista de correo Cconclase <a href="mailto:Cconclase@listas.conclase.net">Cconclase@listas.conclase.net</a><br>
<a href="http://listas.conclase.net/mailman/listinfo/cconclase_listas.conclase.net" target="_blank">http://listas.conclase.net/mailman/listinfo/cconclase_listas.conclase.net</a><br>
Bajas: <a href="http://listas.conclase.net/index.php?gid=2&mnu=FAQ" target="_blank">http://listas.conclase.net/index.php?gid=2&mnu=FAQ</a><br>
</div></div></blockquote></div><br><br clear="all"><div><br></div>-- <br>MIGUEL ALEJANDRO JIMENEZ R.<br>
</div>