¿Qué es la herencia virtual?

La herencia virtual es un tipo de herencia en la que la implementación de una superclase es incompleta y se requiere una subclase para la definición completa de un objeto. Este tipo de herencia se puede usar junto con la herencia única y múltiple, pero se usa más comúnmente en la herencia múltiple. Cualquier clase que herede de una clase base virtual se convierte en una subclase directa de esa clase base. Una clase base virtual puede depender de una subclase para implementar todos sus métodos, pero esto no es un requisito.

C ++ es el lenguaje informático más conocido que utiliza la herencia virtual. Para declarar herencia virtual en C ++, se utiliza la palabra clave «virtual». Tanto la superclase como la subclase deben declarar métodos virtuales con la palabra clave «virtual». Esto le dice al compilador de C ++ que la superclase está incompleta y debe obtener información de la subclase para completarla. Usar la subclase para completar la superclase no significa que las subclases se sobrescriban entre sí si tienen la misma clase base, sino que el compilador de C ++ se encarga de determinar qué piezas van con cada objeto.

Dado que se requiere una clase base virtual para la herencia virtual, las funciones globales en C ++ no se pueden declarar virtuales. Este tipo de herencia solo se puede usar cuando se adhiere a los principios de programación orientada a objetos (OOP). La razón de esto es que las funciones globales no están asociadas con una clase en particular y, por lo tanto, suelen ser independientes por sí mismas. Sin una superclase y una subclase, la herencia no puede ocurrir, por lo que las funciones globales y la herencia virtual son mutuamente excluyentes. En teoría, las funciones globales pueden usarse dentro de funciones virtuales, pero es posible que lo contrario no siempre funcione.

La herencia virtual se utiliza para resolver muchos problemas de programación y uno de los más útiles es la resolución de ambigüedades. En la herencia múltiple, uno puede tener una clase base A que tiene dos subclases, B y C, y luego una clase D que hereda de ambas clases B y C. Este patrón se llama comúnmente el «diamante de la muerte» porque si las clases A, B y C tienen implementaciones del mismo método, no es posible que la clase D determine qué implementación debe usar. La herencia virtual resuelve este problema porque la implementación de cada clase sigue siendo distinta y, por lo tanto, inequívoca. Esta distinción es manejada por objetos internos especializados llamados tablas virtuales (vtables) que realizan un seguimiento de cada tipo de objeto, pero estas tablas no necesitan ser manipuladas explícitamente por un programador porque están integradas en el lenguaje.