Como práctica sólo se debe utilizar la herencia virtual para definir interfaces ya que se utilizan por lo general con la herencia múltiple para asegurarse de que sólo una versión de la clase está presente en la clase derivada. Y las interfaces puras son la forma más segura de herencia múltiple. Por supuesto, si sabe lo que está haciendo, puede usar la herencia múltiple como quiera, pero puede dar como resultado un código quebradizo si no tiene cuidado.
La mayor desventaja con la herencia virtual es si sus constructores toman los parámetros. Si tiene que pasar parámetros al constructor de una clase base virtual, fuerza a todas las clases derivadas a llamar explícitamente al constructor (no pueden confiar en una clase base que llame al constructor).
La única razón que puedo ver para su consejo explícito es que los datos en su clase base virtual pueden requerir parámetros de constructor.
Editar Hice algunos trabajos a domicilio después del comentario de Martin, gracias Marin. La primera línea no es del todo cierto:
Como práctica sólo se debe utilizar herencia virtual para definir las interfaces ya que suelen ser utilizados con la herencia múltiple para asegurar que sólo una versión de la clase es presente en la clase derivada.
La herencia virtual no hace ninguna diferencia si la clase base es una interfaz pura (excepto para errores de compilador ligeramente diferentes, en vc8, si no se implementan todos los métodos). Sólo se hace una diferencia real si la clase base tiene datos, en este caso se termina con un diamante en lugar de una forma de U
Non virtual virtual
A A A
| | / \
B C B C
\ / \ /
D D
En el caso virtuales B y C comparten la misma copia de A.
Sin embargo, todavía estoy de acuerdo con todo lo demás sobre interfaces puras que son la forma más segura de herencia múltiple, incluso si no requieren herencia virtual. Y el hecho de que los parámetros del constructor y la herencia virtual son un problema.
¿Podría proporcionar un enlace o una cita para el consejo? No puedo ver mucho si marca una clase base virtual si no tiene miembros de datos, ya que el propósito más común de la herencia virtual es evitar la duplicación de miembros de la clase base. Por ejemplo, en las bibliotecas estándar, ios_base tiene miembros de datos, y es una clase base virtual (vía ios) de istream y ostream. Así que casi (pero no del todo) diría lo contrario: si vas a tener una clase base virtual, entonces debería tener miembros de datos, o bien heredar de forma no virtual. –