2010-01-31 25 views
19

He leído a mucha gente escribiendo "existe una tabla virtual para una clase que tiene una función virtual declarada en ella".Tabla virtual C++

Mi pregunta es, ¿existe un vtable solo para una clase que tiene una función virtual o también existe para las clases derivadas de esa clase.

por ejemplo

class Base{ 
    public: 
     virtual void print(){cout<<"Base Print\n";} 
}; 
class Derived:public Base{ 
    public: 
     void print(){cout<<"Derived print\n";} 
}; 

//From main.cpp 
Base* b = new Derived; 
b->print(); 

Pregunta: Si no hubiera habido vtable para la clase derivada "de impresión derivada", entonces la salida no habría sido. Por lo que IMO existe un vtable para cualquier clase que tenga la función virtual declarada y también en las clases heredadas de esa clase. Es esto correcto ?

+2

Para completar el experimento, cree la clase derivada2 que hereda de derivada y también sobrescribe la impresión. Impresión de llamada en una instancia de este tipo mediante un puntero a la base ... – VoidPointer

+2

Más información sobre el Vtable @ a continuación Enlace: http://www.learncpp.com/cpp-tutorial/125-the-virtual-table/ –

Respuesta

19

En cuanto a la funcionalidad única virtual función específica se considera, en un enfoque tradicional de la clase derivada VTABLE aplicación necesitaría una versión separada de vtable si y solo si esa clase derivada anula al menos una función virtual. En su ejemplo, Derived anula la función virtual print. Como Derived tiene su propia versión de print, la entrada correspondiente en Derived vtable es diferente de la de Base vtable. Esto normalmente necesitaría un vtable por separado para Derived.

Si Derived no anulan nada en absoluto, formalmente todavía habría una clase polimórfica separada, pero con el fin de realizar sus funciones virtuales funcionan correctamente podríamos haber simplemente reutilizados Base vtable para Derived también. Por lo tanto, técnicamente no habría ninguna necesidad de un vtable por separado para Derived.

Sin embargo, en las implementaciones prácticas, la estructura de datos a la que generalmente nos referimos como "vtable", a menudo contiene también información adicional específica de clase. Esa información adicional es tan específica de la clase que la mayoría de las veces se vuelve imposible compartir tablas virtuales entre las diferentes clases en la jerarquía, incluso si usan el mismo conjunto de funciones virtuales. Por ejemplo, en algunas implementaciones, el puntero vtable almacenado en cada objeto polimórfico apunta a una estructura de datos que también almacena la llamada "información RTTI" sobre la clase.Por este motivo, en la mayoría (si no en todas) las implementaciones prácticas, cada clase polimórfica obtiene su propia tabla virtual, incluso si los punteros de función virtual almacenados en esas tablas son los mismos.

+1

@AndreyT: ¿Conoces alguna página web que explique los conceptos relacionados con 'vtable' para C++ en una buena forma para un principiante? Estoy tratando de entender por qué se necesita un vtable y cómo se implementa exactamente. – Lazer

+0

@Lazer los detalles de implementación no están especificados. La tabla es necesaria para que en tiempo de ejecución el sistema sepa qué versión de una función polimórfica llamar (esto no se puede determinar en tiempo de compilación, considere una operación en un puntero de clase base; la operación podría ser diferente si el puntero apunta a una instancia de clase derivada o instancia de la clase base). Ver https://en.wikipedia.org/wiki/Virtual_method_table – RJFalconer

2

Sí, es cierto. Una clase hereda todos los miembros de datos de su clase base, incluido el vtable. Sin embargo, las entradas vtable se ajustan en consecuencia (por ejemplo, si la clase anula un método virtual de clase base, la entrada correspondiente en el vtable debe apuntar a su propia implementación).

Pero tenga en cuenta que el concepto de 'vtable' es una práctica común utilizada por cada compilador, pero no es obligatorio ni estandarizado.

+0

El vtable es no es miembro ni nada parecido a un miembro. ¿Quieres decir vptr? – curiousguy

3

Sí, su entendimiento es el correcto. Cualquier clase que tenga una base con cualquier función virtual tiene un vtable.

3

Sí, es cierto. En realidad, dada Defintion de la base:

class derived:public base{ 
public: 
void print(){cout<<"derived print\n";} 
}; 

es completamente equivalente a:

class derived:public base{ 
public: 
virtual void print(){cout<<"derived print\n";} 
}; 

... porque ya ha definido impresión como virtual en la base.

Me gustaría que el compilador cumplir esa ...

Cuestiones relacionadas