[C con Clase] Duda sobre clases

Davidson, Steven srd4121 en njit.edu
Mar Mayo 21 17:56:02 CEST 2013


Hola Miguel Alejandro,

2013/5/21 Miguel Alejandro Jimenez Ramirez <cerberbero en gmail.com>

> Bueno pues aca estoy yo otra vez con mis dudas , esta vez es sobre un
> operador en especial el operador :
>
>
>
[CORTE]

Al ejecutarlo vamos a tener 136.
>
> El primer numero 1 , entiendo bien por que existe , ya que la condicion:
> reinterpret_cast<char*>(b1) == reinterpret_cast<char*>(&d)
> es verdadera , lo cual es logico ya que hacemos un casting de b1 y
> convertimos su contenido en un apuntador a char , dentro de b1 vamos a
> tener la referencia a d pero a lo que esta apuntando b1 es el contenido de
> d ,si creamos una funcion para ver su contenido  creeria que es 'c' que es
> valor dado en la clase c.
>
> El 3 , se da por que el contendido de b2 es la referencia a la cual esta
> apuntando es decir la referencia d.
>
>
Ten cuidado con el término "referencia". El operador unitario & (obtener la
dirección de memoria) no es lo mismo que el declarador & (crear una
referencia).

pero el tercero , la verdad no se por qu es falso , ya que si b1 esta
> apuntando a d y b2 esta apuntando a d , y los dos son padres de la clase c
> , no seria como llamar al mismo objeto desde diferentes clases?, bueno no
> se si estoy bien en mi apreciacion epro me gustaria aclarar esta duda y
> ademas saber si mis afirmaciones son correctas.
>
>
Este ejemplo es bastante interesante, porque vemos lo que realmente sucede
con la herencia. La inicialización que hacemos con los punteros se puede
realizar porque los tipos apuntados involucran las clases en la herencia de
'C'. Cuando hacemos esto:

C d;
A *b1 = &d;
B *b2 = &d;

No es meramente un "copiar y pegar" de la dirección de memoria de 'd' a
'b1' ni a 'b2'. El compilador toma en cuenta el hecho de que 'd' contiene
objetos de las clases 'A' y 'B'. Por lo tanto, 'b1' apunta al objeto
"interno" de 'd' de la clase 'A' y 'b2' apunta al objeto interno de 'd' de
la clase 'B'. Esto implica que a nivel bajo, 'b1' apunta a 'A::m_i' y 'b2'
apunta a 'B::m_d'. Obviamente, 'd' comprende 'A::m_i', 'B::m_d', y
'C::m_c'. Por esta razón, la dirección de memoria de 'd' equivale a la
dirección de memoria de 'A::m_i'.

Visto de otra forma, el objeto 'd' ocupa en memoria los siguientes campos:

int m_i;           } A  }
double m_d;   } B  } C
char m_c;             }

Al hacer,

A *b1 = &d;

el compilador apuntará al campo 'm_i'; o sea, b1 == &m_i; y al hacer,

B *b2 = &d;

el compilador apuntará a 'm_d'; o sea, b2 == &m_d.

Por esta razón obtienes diferentes direcciones de memoria. Además, esto es
lógico, porque la clase 'B' es diferente que la clase 'A'; tienen campos
diferentes.


Si quieres, haz otra prueba: cambia el orden de la herencia para 'C'.
Escribe:

class C
    : public B
    , public A
{
...
};

Verás que te da diferentes resultados. Puedes ver los resultados más
fácilmente si muestras las direcciones de memoria:

std::cout << "b1 = " << b1 << "\tb2 = " << b2 << "\t&d = " << &d <<
std::endl;

Con lo que te he dicho antes, creo que puedes ver la razón de las
diferencias en direcciones de memoria con este último cambio.


Espero que esto aclare las dudas.

Steven
------------ próxima parte ------------
Se ha borrado un adjunto en formato HTML...
URL: <http://listas.conclase.net/pipermail/cconclase_listas.conclase.net/attachments/20130521/b57d5743/attachment.html>


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