2010-04-19 16 views
10

Tengo una pregunta, aquí hay dos clases siguientes:Comportamiento de función virtual en C++

class Base{ 
     public: 
      virtual void toString();  // generic implementation 
    } 

    class Derive : public Base{ 
     public: 
      (virtual) void toString(); // specific implementation 
    } 

La pregunta es:

  • Si quiero subclase de la clase Derivar realizar polymophism usando un puntero del tipo Base, ¿es necesaria la palabra clave virtual en el corchete?

  • Si la respuesta es no, ¿cuál es la diferencia entre la función miembro toString de la claseDeducir con y sin virtual?

+1

Es opcional, pero algunos consideran que es una cuestión de buen estilo ser explícito sobre la anulación de funciones de miembro. – pmr

Respuesta

13

C++ 03 §10.3/2:

Si un vf función miembro virtual se declaró en una clase base y en una clase Derivado, derivados directa o indirectamente de Base, un vf función miembro con el mismo nombre y mismo lista de parámetros como Base :: vf es declarado, luego Derivado :: vf también es virtual (sea o no declarado ) e invalida Base :: vf.

+2

+1 para citar referencias reales –

10

Esa palabra clave es estrictamente opcional y no hace ninguna diferencia en absoluto.

+11

No hace ninguna diferencia para el compilador. Para el lector humano, de hecho, puede mejorar la legibilidad. Siempre declaro explícitamente virtual en todos los niveles de herencia. –

7

La propiedad virtual se hereda de la clase base y se asume que está presente incluso si no la escribe.

1

El compilador ya sabe por la palabra clave 'virtual' en la clase base que toString es un método virtual. No es necesario repetirlo.

+4

Podría agregarse que podría marcar una diferencia para el lector humano. – sbi

1

Una función virtual de una vez por siempre una virtuales.

De todos modos, si la palabra clave virtual no se utiliza en las clases subsiguientes, no impide que la función/método sea 'virtual', es decir, que se anule. Así que la siguiente pauta podría ayudar desde una vista de punto de desarrollo del equipo: -

  • Si la función/método se supone que ser anulados, utilice siempre el palabra clave 'virtual'. Esto es especialmente verdadero cuando se usa en las clases de interfaz/base .
  • Si la clase derivada se supone que estar más lejos estado sub-clasificado explícitamente la palabra clave 'virtual' para cada función/método que puede ser anulado.
  • Si no se supone que la función/método en la clase derivada ser sub-clasificado de nuevo, entonces la palabra clave 'virtual' es para ser comentado lo que indica que la función/método fue anulada pero no hay otras clases que lo anulan nuevamente. Por supuesto, esto no impide que alguien anule en la clase derivada a menos que la clase se haga final (no derivable), pero indica que el método no se supone que es anulado. Ej: /*virtual*/ void someFunc();
+0

Para el caso de "para ser anulado siempre", uno puede querer agregar el especificador puro también. – Myke

+0

Creo que debe haber una coma entre "anulado" y "siempre". es decir, "utilice siempre la palabra clave' virtual' "y no" siempre anulado ". –

+0

@Ben: tienes razón, Thnx. – Abhay

0

No importa que el compilador si está o no suministrar la virtuales de palabras clave en las versiones derivadas de la función.

Sin embargo, es una buena idea proporcionarlo de todos modos, de modo que cualquier persona que vea su código podrá decir que es una función virtual.

0

Es una cuestión de buen estilo, y el usuario-programador sabe lo que está pasando. En C++ 0x puede usar [[anular]] para hacerlo más explícito y visible. Puede usar [[base_check]] para forzar el uso de [[anular]].

Si no quiere o no puede hacer eso, simplemente use la palabra clave virtual.

Si obtiene sin virtual toString, y emite una instancia de Derive de nuevo a Base, llamar aString() llamaría realmente a toString() de Base, ya que por lo que sabemos es una instancia de Base.

Cuestiones relacionadas