Bueno he comprobado por mí mismo, porque hay una gran cantidad de cosas que podemos pensar en:
#include <iostream>
using namespace std;
class A
{
public:
virtual void v() { cout << "A virtual" << endl; }
void f() { cout << "A plain" << endl; }
};
class B : public A
{
public:
virtual void v() { cout << "B virtual" << endl; }
void f() { cout << "B plain" << endl; }
};
class C : public B
{
public:
virtual void v() { cout << "C virtual" << endl; }
void f() { cout << "C plain" << endl; }
};
int main()
{
A * a = new C;
a->f();
a->v();
((B*)a)->f();
((B*)a)->v();
}
de salida:
A plain
C virtual
B plain
C virtual
Creo que una respuesta buena, simple y corto podría parecerse a esto (porque creo que las personas que pueden entender más puede memorizar por lo tanto menos necesidad de explicación breve y sencilla):
métodos cheques virtuales para los datos de la instancia del puntero señala, mientras que los métodos clásicos no llaman al método correspondiente al tipo especificado.
El punto de esa característica es la siguiente: supongamos que tiene una serie de Atléticos. La matriz puede contener B, C, (o incluso tipos derivados). si desea llamar secuencialmente el mismo método de todas esas instancias, debería llamar a cada una de las que haya sobrecargado.
Me resulta bastante difícil de entender, y obviamente cualquier curso de C++ debería explicar cómo se logra esto, porque la mayoría de las veces solo se les enseña sobre funciones virtuales, pero hasta que comprendan cómo el compilador las entiende y cómo el ejecutable manejará las llamadas, estás en la oscuridad.
Lo que pasa con VFtables es que nunca me han explicado qué tipo de código agrega, y obviamente es aquí donde C++ requiere mucha más experiencia que C, y esta podría ser la razón principal por la que C++ fue etiquetado como "lento" en sus primeros días: de hecho, es poderoso, pero al igual que todo, es poderoso si sabes cómo usarlo, o simplemente te "volarás toda la pierna".
Creo que un ejemplo explícito hubiera sido muy apreciado. – jokoon