2012-01-19 17 views

Respuesta

9

Depende mucho de la implementación, pero en general obtendrá un objeto vtable por clase que tiene funciones virtuales (las clases sin funciones virtuales o bases no las necesitan) y un vptr por objeto de una clase con un vtable (apuntando al vtable de la clase).

Las cosas se vuelven más complejas si tiene múltiples clases de herencia y de base virtual, que se pueden implementar de muchas maneras. Algunas implementaciones usan un vtable agregado por clase base adicional (por lo que se termina con un vtable por clase base por clase), mientras que otros usan un solo vtable con información adicional. Esto puede provocar la necesidad de múltiples vptrs por objeto.

La palabra clave virtual en B es irrelevante: si la función es virtual en la clase base, será virtual en las clases derivadas independientemente.

+0

ahora si modifico mi pgm como a continuación: elimino la palabra clave virtual de la clase derivada. Ahora, ¿cuántos vtables se crearán? – CodeCodeCode

+2

@Pal - No hay diferencia, la función sigue siendo virtual. –

+0

@Bo Persson: la función es virtual pero, ¿habrá un vtable creado para la clase derivada también? – CodeCodeCode

3

Tenga en cuenta que esto depende estrictamente de la implementación.
C++ Standard no habla de vptr o vtable, el mecanismo virtual se omite como un detalle de implementación para los compiladores. Prácticamente, los compiladores pueden implementarlo sin usar vptr o vtable. Sin embargo, casi todos los compiladores conocidos lo implementan usando vptr y vtable.

Dado lo anterior, para responder a su pregunta:

Cada clase tendrá su propia tabla virtual.
Si bien cada objeto tiene su propio puntero virtual.

+0

Gracias Als por la respuesta, ahora estoy un poco confundido. por favor, explíqueme si elimino la palabra clave virtual de la clase B (derivada) y, a continuación, ¿cuántos vtables se crearán? – CodeCodeCode

+0

@CodeCodeCode si elimina la palabra clave virtual de la clase B (derivada) y, a continuación, ¿cuántos vtables se crearán? la respuesta sigue siendo la misma 2 una para base y derivada. –

+0

@aloksave Leí en alguna parte que, como una clase base tiene una función virtual, tendrá un vptr y la misma se heredará a la clase derivada pero apunta a la clase derivada vtable. ¿Puedes ayudarme con eso? –

7

Básicamente, 2. Uno para class A, uno para class B (vftables) y 2 vfptrs, uno para a1 y uno para b1.

Sin embargo, esto no es un mandato estándar, por lo que tampoco podría tener ninguno. (Por lo general implementaciones utilizan vftables, pero no es obligatorio.

Nota @R. Martinho Fernandes con optimizaciones sobre, que no tendrá los objetos creados, por lo que no vfptrs.

+0

+1 para indicar realmente los números como la pregunta –

12

Este programa puede ser optimizado para ser exactamente igual éste:

int main(){} 

por lo tanto, "ninguno" es una posibilidad

+0

Quiero +1 para gracioso, pero ... –

+0

No es necesario, podría tener 2 o 1000 (no está obligado a ser optimizado). Pero +1 para el pensamiento :) –

+0

int main() {} es suficiente para escribir un programa en C++. sin necesidad de ninguna otra línea de código. :) – CodeCodeCode

2
se creará

mesa Virual sólo si al menos 1 función virtual es allí en la clase Base, que se hereda de ninguna manera a la. classes.it derivadas no importa incluso si elimina la palabra clave virtual de la clase derivada B porque ya tiene una diversión virtual() en A. Así que el número de tablas virtuales será 2 (como su base de clase) y el número de virtual ptrs también será 2, como su base de objeto.VTABLE para A --- v_ptr *, A :: fun()

& VTABLE para B --- V_ptr * (que se heredó de A), B :: diversión()/* B tiene acceso a ambos A :: diversión & diversión de B(), pero como mencionamos A :: fun() como virtual, la tabla virtual de B se llena con la versión más derivada de la función, fun(), que no es más que B :: diversión(). espero que esto aclare ur duda

0

habrá 2 vtables, uno para clase a y uno para la clase B . Y habrá 3 vptrs, uno en a1 y dos en b1 (uno que apunta a vtable de clase A y otro que apunta a vtable de clase B).