2012-06-07 6 views
5

Según tengo entendido, la ubicación de la tabla del puntero de función virtual en un objeto depende del compilador.
¿Hay algún pros/contra de colocar este puntero al principio del objeto vs al final o viceversa?ubicación del puntero de la tabla de funciones virtuales en el objeto

+0

posible duplicado de [¿Recuperar vptr (puntero a tabla virtual también conocido como VTABLE) desde la utilidad Objdump?] (Http://stackoverflow.com/questions/10549311/retrieving-vptrpointer-to-virtual-table-aka-vtablefrom- the-objdump-utility) – iammilind

Respuesta

7

La mera existencia de una tabla de funciones virtuales depende del compilador (pero todos los compiladores sí), y la ubicación tampoco es obligatoria ... En todos los compiladores de los cuales Sé los detalles, el vptr se almacena en el comienzo del objeto. La razón es que proporciona una ubicación uniforme. Considere una jerarquía de clases:

struct base { 
    T data; 
    virtual void f(); 
}; 
struct derived : base { 
    T1 data; 
    virtual void g(); 
}; 

Si el VPTR se almacenó en el extremo del objeto, entonces sería después sizeof(T) bytes para un objeto de tipo completo base. Ahora cuando tiene un objeto de tipo completo derived, el diseño del objeto secundario base debe ser compatible con el diseño de un objeto completo base, por lo que el vptr todavía tendría que ser vptr dentro del objeto, que estaría en algún lugar del medio del objeto derived (sizeof(T) desde el principio, sizeof(T1) antes del final). Por lo tanto, ya no estaría en el final del objeto.

Además, dado un puntero this, una llamada virtual requiere una vía indirecta a través de la viable, que es básicamente la eliminación de referencias vptr, añadiendo un desplazamiento y saltar a la posición de memoria almacenada allí. Si el vptr se almacenó al final del objeto, para cada llamada virtual habría una adición adicional a this antes de desreferenciar el vptr.

+0

En teoría, podría tener vptr's al final del subobjeto base-class y el objeto completo. Tendría algún sentido: tener el vptr 'Derived' para las funciones virtuales que no aparecen en' Base'. Pero la sobrecarga por objeto no es tan agradable. – MSalters

+0

¡Gran explicación! –

4

Sí, depende completamente de la implementación.
Para una jerarquía de herencia simple, se encuentra al principio del objeto, pero para una jerarquía compleja no lo será.
De todos modos, cualquier código fuente que escriba no debe depender de dónde se encuentra, de hecho, cualquier código que escriba no debe depender de la existencia de una tabla virtual o un puntero de tabla virtual.
El estándar C++ no exige que el despacho virtual se implemente a través de tabla virtual y puntero, una implementación es libre de implementarlo usando otro método de implementación. Sin embargo, todos los compiladores convencionales implementan esto a través del mecanismo de puntero de tabla. puede diferir en la implementación exacta de dónde se encuentra el puntero, etc.

Cuestiones relacionadas