Pregunta

Actualización: se ha sustituido el ejemplo destructor con un ejemplo del método de atención recta.

Hola,

Si tengo el siguiente código:

class a
{
public:
    virtual void func0(); // a has a VTable now
    void func1();
};
class b : public a
{
public:
    void func0() { a::func0(); }
    void func2();
};
  1. ¿Hay una Vtable en B? B no tiene funciones virtuales, pero llama a un :: func0 () de b :: func0 ()
  2. func1 residen
  3. hace en un Vtable? No es virtual.
  4. ¿El func2 residir en un Vtable?
  5. ¿Las respuestas a lo anterior será diferente si no había una llamada de un :: func0 () en b :: func0 ()?

Gracias

¿Fue útil?

Solución

Si se declara funciones virtuales que también debe declarar su destructor virtual; -).

  1. B tiene una mesa virtual, ya que tiene una función virtual, a saber func0(). Si se declara una función (incluyendo un destructor) virtual en una clase base, todas sus clases derivadas tendrán la función con misma firma virtual. Y provocará que tengan una vtable. Por otra parte, B tendría la viable, incluso si no se declara explícitamente func0 en ella.

  2. funciones no virtuales están no referenciado a través de vtables.

  3. Vea 2.

  4. No. vtables clases se construyen sobre la base de declaraciones de clases. Los cuerpos de funciones de clase (por no hablar de otras funciones) no se tienen en cuenta. Por lo tanto, B tiene un vtable, porque su función es func0() virtual.

También es un detalle difícil, aunque no es la esencia de su pregunta. Usted declaró que su función B::func0() como en línea. En compilador gcc, si una función virtual se declara en línea, que conserva su ranura en la tabla virtual, la ranura que apunta a una función especial emitida por esa línea uno (que cuenta como teniendo su dirección, lo que hace que la línea emitida). Eso significa que, si la línea es Funciton no influye en la cantidad de ranuras de vtable y su necesidad para una clase.

Otros consejos

  1. Sí, porque su clase base tiene uno; También su destructor es virtual (aunque no lo declaró virtual), porque el destructor de la clase base es virtual.

  2. No

  3. No.

  4. No. En realidad no creo que el código actual es legal: el compilador invocará el destructor Una vez que invoca el destructor B, incluso si usted no llama explícitamente ~ ~ A partir de B; así que no creo que se debe invocar ~ ~ A partir de B, incluso si el compilador le permite.

Haciendo referencia al ejemplo actualización:

  1. Si, b tiene un vtable. Tenga en cuenta que b :: func0 () es virtuales (prevalece sobre una :: func0 ()), a pesar de que no etiquetar explícitamente como virtual. Raro C ++ "vacío legal", supongo.
  2. No. funciones no virtuales no residen en la viable.
  3. Ver 2.
  4. No. Usted ha redefinido a: func0 (); no importa si se llama a un :: func0 () o no.

Algunas notas adicionales (compilador dependientes, pero estas son generalizaciones bastante comunes):

  • Cada instancia de b tendrá un puntero a una vtable, porque se deriva de una clase que tiene funciones virtuales.
  • Este sería el caso de incluso si no ha definido b :: func0 () .
  • En esta situación, el compilador podría tener instancias de b punto a a 's estática vtable, o podría crear un vtable estática de b y llenarlo con punteros a punteros a miembros de a .
  • Pero sigue siendo requerida , de modo que usted pueda acceder correctamente a una instancia de b a través de un puntero a a .
  • Si la función de la clase base es virtual a continuación, si omiso de esa función en la clase derivada es implícitamente virtuales, incluso si no se especifica explícitamente. Si la clase tiene una función virtual, entonces tiene una mesa v.
  • Sólo las funciones virtuales presentan en vtable, function1 voluntad no residen en vtable
  • function2 no residirá en vtable misma razón anterior
  • Creación de vtable no depende de si se llama a esa función de la clase de base o de otro lugar. llamada de función no decide la creación de vtable.
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top