2011-08-26 16 views
9

Soy nuevo, así que no me moleste :) Por lo que mi profesor le había dicho hace algún tiempo, el orden de la tabla virtual es importante. ¡¡Pero no entiendo la razón de eso !!?¿Es importante el orden de la tabla virtual?

Dado el siguiente código:

class A 
{ 
public: 
    A() {cout <<"1" << endl;}; 
    A (const A& s) {cout << "2" << endl;} 
    ~A() {cout << "3" << endl;} 
    void f1() {cout << "4" << endl; f2();} 
    virtual void f2() = 0; 
    virtual void f3() {cout << "5" << endl;} 

}; 


class B : public A 
{ 
public: 
    B() {cout << "6" << endl;} 
    B(const B& b) : A(b) {cout << "7" << endl;} 
    ~B() {cout << "8" << endl;} 

    virtual void f1() {cout<<"9"<<endl;} 
    void f2() {cout<<"lO"<<endl; f4();} 
    virtual void f2(int i) {cout << "11" << endl;} 
    virtual void f4() {cout << "12" << endl; f3();} 

}; 

Dijo que la orden es:

A's vtable : 
A::f2() 
A::f3() 

B's vtable : 
B::f2() 
A::f3() 
B::f1() 
B::f2(int) 
B::f4() 

Pero no entiendo por qué es importante? Dijo que el vtable es inútil si es no por su orden correcto, ¿puede explicar por qué?

Respuesta

8

El orden del vtable es importante para que las cosas funcionen correctamente, pero solo para el compilador (es decir, no es necesario que se preocupe porque lo soluciona).

Si el compilador lo puso fuera de servicio por sí mismo, entonces sí, las cosas se romperían, porque las funciones se buscan por compensación (por lo que una compensación produciría una función aleatoria que sería catastrófica). Pero el programador promedio no lo hace Necesito preocuparme sobre en qué orden está el vtable.

1

El vtable es una tabla de "búsqueda". Básicamente es un mapa de punteros a las funciones virtuales de la clase. Si está fuera de servicio, los punteros señalarán las funciones incorrectas. Podrían ocurrir cosas malas si, por ejemplo, desea llamar al B:f1(), que no toma ningún argumento, sino que se llama B::f2(), que toma un int.

16

No hay ninguna noción de vtables en el estándar C++. Es solo que la mayoría de las implementaciones (si no todas) lo usan para el despacho virtual. Las convenciones exactas, sin embargo, están totalmente definidas por la implementación.

Dicho eso ... El orden de las funciones es importante, pero no para el programador, sino para el compilador: puede organizar sus funciones como lo desee en su código. Sin embargo, el compilador pondrá típicamente cada puntero de función en un lugar específico en el vtable, que se ha dedicado a esa función. Para que cuando necesite llamar al f() conozca el índice de la función f() y tome ese puntero del vtable.

Esta pregunta podría ayudar también: Virtual dispatch implementation details

+0

muchas gracias !!! A todos ustedes ! –

+1

@Ron_s asegúrese de hacer clic en la marca de verificación en la parte superior izquierda de esta respuesta si contestó su pregunta. –

2

Cada cliente de la viable necesita conocer el orden correcto para que puedan encontrar el método correcto para llamar. Pero mientras todas las partes estén de acuerdo con la orden, no importa cuál sea esa orden.

5

Solo es importante que las clases declaren interfaces para ABI externo (por ejemplo, COM/XPCOM).

La mayoría de las veces no es importante y no hay ninguna razón para preocuparse por ello.

+1

+1 abi externo es un muy buen punto –

+2

+1 La única razón por la que el diseño de vtable es estándar en la plataforma de Windows es por COM. Como proveedor de compiladores, si desea admitir COM, debe seguir la implementación de Microsoft. Sin embargo, las características más avanzadas no utilizadas por COM, como la herencia virtual o la herencia múltiple de las no interfaces, dependen de la implementación. –

0

No estoy seguro de lo que quería decir, pero voy a tratar de explicar cómo funciona:

En primer lugar, C++ define los métodos de nombre y firma. Entonces, cuando C++ inicia una tabla virtual de clase, reemplazará todas las funciones virtuales de la clase base con las funciones virtuales derivadas con el mismo nombre y firma.

Cuando una clase deriva otra clase, en realidad está construida sobre ella.Por lo tanto existe la clase base como parte del bloque de memoria (complicado, leer aquí - Virtual inheritance)

Las tablas virtuales acaba de celebrar un "puntero" para la función correcta en función del tipo en tiempo de ejecución.

Cuestiones relacionadas