Downcasting utilizando el ‘static_cast’ en C ++

Considerar:

class base { base(); virtual void func(); } class derived : public base { derived(); void func(); void func_d(); int a; } main { base *b = new base(); sizeof(*b); // Gives 4. derived * d = static_cast(b); sizeof(*d); // Gives 8- means whole derived obj size..why? d->func_d(); } 

En el código anterior hice downcasting de un puntero base que apunta al objeto base al puntero de clase derivado. Me pregunto cómo el puntero derivado tiene todo el objeto de clase derivado. Puedo llamar a la función de clase derivada (declarada solo en la clase derivada). No entendí el concepto aquí.

Usar static_cast para convertir un objeto en un tipo no tiene un comportamiento indefinido . Los síntomas de UB varían ampliamente. No hay nada que diga que UB no puede permitir que la función miembro derivada sea llamada con éxito (pero no hay nada que garantice que así sea, así que no cuente con ella).

Aquí está la regla para static_cast usando static_cast , que se encuentra en la sección 5.2.9 ( [expr.static.cast] ) del estándar C ++ (redacción C ++ 0x):

Un prvalue de tipo “puntero a cv1 B “, donde B es un tipo de clase, se puede convertir a un prvalue de tipo “puntero a cv2 D “, donde D es una clase derivada de B , si es una conversión estándar válida de “puntero” a D “a” puntero a B “existe, cv2 es la misma calificación cv, o mayor cv-cualificación que, cv1 , y B no es una clase base virtual de D ni una clase base de una clase base virtual de D . El valor del puntero nulo se convierte en el valor del puntero nulo del tipo de destino. Si el prvalue de tipo “puntero a cv1 B ” apunta a un B que en realidad es un subobjeto de un objeto de tipo D , el puntero resultante apunta al objeto circundante de tipo D De lo contrario, el resultado del lanzamiento no está definido.

El único molde que controla el tiempo de ejecución es dynamic_cast<>() . Si hay alguna posibilidad de que un yeso no funcione en el tiempo de ejecución, entonces este molde debe ser utilizado.

Por lo tanto, el fundido de leaf-> root (up casting) static_cast<>() funciona bien.
Pero el lanzamiento desde root-> leaf (down casting) es peligroso y (en mi opinión) siempre debe hacerse con dynamic_cast<>() ya que habrá dependencias en la información del tiempo de ejecución. El costo es leve, pero siempre vale la pena pagar por la seguridad.

sizeof existe en tiempo de comstackción. No sabe ni le importa que en el tiempo de ejecución, su objeto base no apunte a un derived . Está intentando influir en el comportamiento en tiempo de comstackción con una variable en tiempo de ejecución, que es fundamentalmente imposible.