test tag sobre sabes preguntas para papa padres mis hijos hijo hacerle entrevista cuanto conozco c++ casting parent-child dynamic-cast reinterpret-cast

c++ - tag - ¿Qué tipo de cast para ir de padres a hijos?



tag del padre (3)

Esta pregunta es sobre qué estilo de C ++ se debe usar para hacer esta conversión. Soy consciente de que un elenco de estilo C puede lograr esto.

Para la siguiente estructura de class :

class Foo {}; class Bar : public Foo {};

Diga que me dieron: Foo* ptr; y quiero lanzarlo a un Bar* qué tipo de yeso debería usar? Parece que debo usar dynamic_cast tal como está:

Utilizado para la conversión de tipos polimórficos

Quería evitar el dynamic_cast ya que es un lanzamiento de tiempo de ejecución.


Por el bien de la claridad:

Quería evitar el dynamic_cast ya que es un lanzamiento de tiempo de ejecución.

Bueno, tiene un tipo de tiempo de ejecución (dada una referencia de tipo estático a la clase base, generalmente no puede conocer el tipo dinámico del objeto), por lo que un lanzamiento en tiempo de ejecución es la única opción completamente segura.

Si creía que su objeto era realmente un Bar , pero estaba equivocado, dynamic_cast<Bar*> le dará un nullptr , o dynamic_cast<Bar&> lanzará una excepción. De cualquier forma, tienes la oportunidad de lidiar con tu error en tiempo de ejecución en tiempo de ejecución. Como MM señaló, esto solo está disponible si su clase base tiene o hereda al menos un método virtual.

Ahora, si, por casualidad, puede estar estáticamente seguro de que el tipo dinámico de su objeto es realmente Bar , puede usar static_cast . Sin embargo, si se equivoca, tiene un Comportamiento no definido y no tiene la oportunidad de detectar o tratar el error.

p.ej.

struct Foo { virtual ~Foo(){} }; struct Bar : public Foo {}; // safe, may return nullptr Bar* safe_ptr_cast(Foo *f) { return dynamic_cast<Bar*>(f); } // safe, may throw but you can catch it Bar& safe_ref_cast(Foo &f) { return dynamic_cast<Bar&>(f); } // unsafe - if you''re wrong, you just broke everything Bar* unsafe_ptr_cast(Foo *f) { return static_cast<Bar*>(f); }

Por cierto, si su problema con el tiempo de ejecución es rendimiento, arriesgar UB para ahorrar tiempo nocional antes de tener código para perfil es la definición de optimización prematura.


Tiene razón en que dynamic_cast suele ser el más adecuado para esta situación. Sin embargo, si sabe que el puntero apunta realmente a un objeto de la clase derivada, puede usar static_cast para la conversión. Si te equivocas y el puntero no es la clase derivada, obtendrás un comportamiento indefinido.


static_cast funcionará bien siempre que estés seguro de que el objeto que estás lanzando realmente es del tipo que esperas que sea. Basado en el ejemplo que dio, parece que está seguro.