2010-12-28 22 views
18

Veo en this entry que la herencia virtual agrega sizeof (puntero) a la huella de memoria de un objeto. Aparte de eso, ¿hay algún inconveniente para mí al usar herencia virtual por defecto y herencia convencional solo cuando sea necesario? Parece que llevaría a un diseño de clase más a prueba de futuro, pero tal vez me estoy perdiendo un escollo.En C++, ¿debería usar casi siempre la herencia virtual?

+2

El orden de inicialización de las clases base no es obvio para la mayoría de las personas. Por lo tanto, el costo de mantenimiento aumenta. –

+0

La herencia virtual agrega un puntero interno solo en algunas implementaciones. Itanium ABI no utiliza punteros internos, solo vptr. – curiousguy

Respuesta

20

Las desventajas son que

  1. Todas las clases tendrán que inicializar todos sus bases virtuales todo el tiempo (por ejemplo, si A es base virtual de B, y C se deriva de B, sino que también tiene que inicializar una misma)
  2. Tienes que usar el más caro dynamic_cast donde sea que uses un static_cast (puede o no ser el problema, dependiendo de tu sistema y si tu diseño lo requiere).

El punto 1 solo hace que no valga la pena, ya que no puede ocultar sus bases virtuales. Casi siempre hay una mejor manera.

+0

Oh dios (1) es horrible. ¡Gracias! ¿Podrías ser más explícito sobre (2)? ¿Quiere decir que el compilador arroja un error si trato de usar static_cast (my_virtual_base_instance)? – SuperElectric

+1

@SuperElectric: ¿por qué es (1) horrible? ¿Sería mejor si un subobjeto base no se inicializara? ;) – Yttrill

+3

Comentarios como "no vale la pena" muestran una falla completa al no entender el propósito de las bases virtuales: la herencia virtual debe * siempre * ser utilizada cuando se está subclasando una abstracción. No hay solución alternativa u otra posibilidad, si no la usa no puede usar múltiples subclases de abstracciones sin volver atrás y corregir su error de diseño, rompiendo así la encapsulación. – Yttrill

11

En mi experiencia, la herencia virtual (a diferencia de métodos virtuales) casi nunca es necesaria. En C++ se usa para direccionar el "diamond inheritance problem", que si se evita la herencia múltiple en realidad no puede suceder.

Estoy bastante seguro de que nunca he encontrado herencia virtual fuera de los libros en C++, que incluye tanto el código que escribo como el millón de sistemas de línea que mantengo.

+0

La biblioteca de flujos de E/S de C++ estándar usa herencia virtual. Pero sí, aparte de eso, en general es bastante raro. –

+0

Greg: +1 excelente generalización en todo el lío de herencia virtual. –

+1

Hmm ... Ya sé para qué sirve (estoy pensando en usarlo), y entiendo que es raro (código en C++), pero la pregunta que planteé fue "cuáles son los inconvenientes de la herencia virtual". – SuperElectric