[C con Clase] Otra duda

Miguel Alejandro Jimenez Ramirez cerberbero en gmail.com
Sab Nov 3 21:18:05 CET 2012


Muchisimas gracias Steven estaba quebrandome la cabeza y no lograba
entender como el compilador ejecutaba este codigo.

Cordialmente

2012/11/3 Davidson, Steven <srd4121 en njit.edu>:
> Hola Miguel Alejandro,
>
> 2012/11/3 Miguel Alejandro Jimenez Ramirez <cerberbero en gmail.com>:
>> #include <iostream>
>>
>> class A
>> {
>> public:
>>     A(int n = 0)
>>         : m_i(n)
>>     {
>>         std::cout << m_i;
>>         ++m_i;
>>     }
>>
>> protected:
>>     int m_i;
>> };
>>
>> class B
>>     : public A
>> {
>> public:
>>     B(int n = 5) : m_a(new A[2]), m_x(++m_i) { std::cout << m_i; }
>>
>
> Esto es un error, que algunos compiladores declararán como aviso. El
> problema es que inicializas en el orden incorrecto del orden de las
> declaraciones de los datos miembro. Debería ser así:
>
> B(int n = 5) : m_x(++m_i), m_a(new A[2])  { std::cout << m_i; }
>
> porque el orden de declaración de los datos miembro es:
>
> A m_x;
> A *m_a;
>
> Implícitamente, se invocará el constructor de la clase base, 'A',
> aunque personalmente, recomiendo hacerlo explícitamente. Por lo tanto,
> el resultado sería,
>
> B(int n = 5) : A(), m_x(++m_i), m_a(new A[2])  { std::cout << m_i; }
>
> o si quieres ser más explícito,
>
> B(int n = 5) : A(0), m_x(++m_i), m_a(new A[2])  { std::cout << m_i; }
>
>>     ~B() { delete [] m_a; }
>>
>> private:
>>     A m_x;
>>     A *m_a;
>> };
>>
>
> [CORTE]
>
>> al ejecutarlo veran que el resultado es 02002.
>>
>> La verdad en mi analisis yo vi otro resultado , pense que era 01242
>>
>> por que ? se preguntaran ustedes , y pues he aqui mi raciocinio:
>>
>
> Veamos su análisis.
>
>> El primer 0:
>>
>> como en el main declaramos un objeto de la clase B , entonces me
>> dirigo hacia la clase B, veo que es una clase derivada de la clase A ,
>> entonces veo el constructor de la clase A :
>>
>> class A
>> {
>> public:
>>     A(int n = 0)
>>         : m_i(n)
>>     {
>>         std::cout << m_i;
>>         ++m_i;
>>     }
>>
>> protected:
>>     int m_i;
>> };
>>  y veo que imprime m_i , que tendria el valor de 0 ya que el
>> constructor no esta recibiendo ningun parametro.
>>
>
> Correcto.
>
>> Luego veo el constructor de B , entonces veo que hay un objeto que es
>> un apuntador a la clase A , y que se crea un espacio de memoria para
>> una clase A y es un vector de dos posiciones , no se si lo que voy a
>> decir esta bien , pero pense que se llamaba al constructor de A por
>
> Correcto. Como no damos ningún parámetro, implícitamente éste es 0 por
> la definición del constructor. Es decir, estamos invocando
> implícitamente: A(0).
>
>> cada una de las dos posiciones , por lo tanto imprimia 1 , el cuel era
>
> No. Cada objeto en el array dinámico, apuntado por 'm_a', no tiene
> nada que ver con el objeto de la clase 'B', que está en 'main()'. Por
> lo tanto, estos tres objetos no comparten el dato, 'm_i', de la clase
> 'A'. Por consiguiente, tenemos que 'm_i' es 0 (cero) en ambos casos de
> los objetos en el array dinámico, apuntado por 'm_a'.
>
>>
>> Al final todo lo que habia pensado estaba mal , por que la ejecucion
>> del programa muestra otro resultado , por lo tanto mi duda es cual es
>> el procedimiento que hace este programa para imprimir : 02002??
>>
>
> Bien. El proceso para crear el objeto 'b', en 'main()', es el siguiente:
>
> 1.  Invocamos A() que implica: A(0) y por tanto, 'b.A::m_i' es 0;
> mostramos su valor: 0; y lo incrementamos a 1, por lo que, 'b.A::m_i'
> es 1.
>
> 2.  Inicializamos 'm_x', ya que el orden de instanciación indica que
> creamos 'm_x' primero. Con: m_x(++m_i), incrementamos 'm_i'; es decir,
> 'b.A::m_i' es ahora 2. Pasamos este valor al constructor de 'A'; es
> decir, invocamos 'A(2)'.
>
> Esto implica que, 'b.m_x.m_i' es 2; mostramos su valor: 2; y lo
> incrementamos a 3, por lo que 'b.m_x.m_i' es 3.
>
> 3.  Inicializamos 'm_a' con el array dinámico de dos objetos de la
> clase 'A'. Esto implica que cada constructor invocado inicializa su
> 'm_i' a 0, muestra su valor, y aumenta su valor a 1. Es decir,
> 'b.m_a[0].m_i' es al final 1 al igual que 'b.m_a[1].m_i'.
>
> 4. Ahora mostramos 'b.A::m_i' que es 2, a consecuencia de los pasos #1 y #2.
>
> Al final, por cada paso, se muestra:
>
> #1 =>  0
> #2 =>  2
> #3 =>  0
> #3 =>  0
> #4 =>  2
>
>
> Espero que esto aclare la duda.
>
> Steven
>
> _______________________________________________
> Lista de correo Cconclase Cconclase en listas.conclase.net
> http://listas.conclase.net/mailman/listinfo/cconclase_listas.conclase.net
> Bajas: http://listas.conclase.net/index.php?gid=2&mnu=FAQ



-- 
MIGUEL ALEJANDRO JIMENEZ R.




Más información sobre la lista de distribución Cconclase