2010-02-11 22 views
19

Vi el código en una clase derivada recientemente en la que el programador puso virtual en frente de las funciones anuladas. ¿Es esto común? Pensé que era muy extraño y me pilló desprevenido.Usando 'virtual' en la clase derivada

Editar: No estoy preguntando qué hace virtual, estoy preguntando por qué alguien pondría virtual en una clase derivada que ya está anulando funciones virtuales en su clase base.

EX:

class B { 
public: 
    virtual void foo(); 
    .... 
}; 

class D : public B { 
public: 
    virtual void foo(); // could have just put void foo(); 
    ... 
}; 
+4

Siempre hago esto también, solo para documentar mi código. –

+3

Esto es algo en lo que creo que C# es mejor, forzando a las clases derivadas a usar la palabra clave 'override'. – dalle

+0

Esta es la pregunta perfecta, que respondió muchas de mis consultas sobre cómo funciona la tecnología virtual. Gracias @Person –

Respuesta

25

virtual se necesita para las funciones overrideable al más alto nivel (menos derivado). Es opcional, pero inofensivo a niveles más bajos (más derivados). Es bueno para auto-documentar el código.

+3

Exactamente. El compilador ya lo sabe, pero es posible que otras personas que leen tu código deban realizar un seguimiento a través de varios archivos de encabezado para averiguarlo. –

3

Supongo que conoce el propósito de la palabra clave virtual pero se pregunta por qué aparece de repente en un subtipo. Si estoy equivocado, mi respuesta probablemente no tendrá mucho sentido, pero cualquier referencia de C++ servirá.

Es perfectamente legal poner virtual en una clase derivada. Como resultado, si tiene una referencia o un puntero a esa clase o cualquiera de sus subclases, las invocaciones de esta función se vincularán dinámicamente en función del tipo de tiempo de ejecución.

Si bien es legal, sin embargo, no se considera un buen diseño tener un método no virtual en la clase base y virtual en una versión anulada.

Una razón es que podría tener una instancia de la clase derivada, y luego un puntero a la base y un puntero a la derivada, y tener ambos punteros apuntando a esta instancia. Invocar la misma función en cada puntero tendría un resultado diferente, ya que al invocar el puntero declarado con la clase base se apuntaría a la definición en la clase base.

4

No veo nada extraño en él. En muchos casos (si no la mayoría de las veces) los programadores crean la declaración de la función de anulación en la clase derivada copiando y pegando desde la clase base. No tiene sentido gastar el esfuerzo adicional para eliminar manualmente el especificador virtual redundante. Además, el virtual explícito hace que sea más fácil ver qué funciones son virtuales.

8

Es muy común. Muchas guías de estilo lo recomiendan, p. Google. El propósito es mejorar la legibilidad del código.

+1

El enlace no funciona –

+0

Nuevo enlace aquí http://google.github.io/styleguide/cppguide.html#Inheritance El enlace dice que debe utilizarse 'override' o' virtual' * pero no both *. –

1

Esto ayudará si futuras derivaciones también. Si alguien quiere derivar la clase D y tienen funciones virtuales, entonces es fácil de entender

4

Otra forma de mejorar la legibilidad es usar algo como esto:

class B { 
public: 
    virtual void foo(); 
    .... 
}; 

class D : public B { 
public: 
    /*override*/ void foo(); 
    ... 
}; 
3

Estas respuestas (y esta práctica) son anticuados . A partir de C++ 11, debe usar override keyword para especificar explícitamente que una función virtual prevalece sobre otra función virtual. Tu compilador arrojará un error si tratas de override algo que no es una función virtual en la clase base.

Cuestiones relacionadas