Pregunta Exigir anulaciones de funciones virtuales para utilizar la palabra clave anular


C ++ 11 agregado override para asegurarse de que las funciones miembro que escriba que pretenda anular las funciones virtuales de la clase base realmente lo hagan (o no se compilen).

Pero en una gran jerarquía de objetos, a veces podría terminar escribiendo accidentalmente una función de miembro que anula una clase base virtual cuando no tenía la intención de hacerlo. Por ejemplo:

struct A {
    virtual void foo() { }  // because obviously every class has foo().
};

struct B : A { ... };

class C : B {
private:
    void foo() {
        // was intended to be a private function local to C
        // not intended to override A::foo(), but now does
    }
};

¿Hay alguna bandera / extensión del compilador que al menos emita una advertencia en C::foo ? Para legibilidad y corrección, solo me gustaría hacer cumplir que todas las anulaciones usan override.


32
2018-03-19 13:10


origen


Respuestas:


Parece que la versión GCC 5.1 agregó exactamente el advertencia Estaba buscando:

-Wsuggest-override
  Advierta sobre la anulación de las funciones virtuales que no están marcadas con la palabra clave override.

Compilando con -Wsuggest-override  -Werror=suggest-override entonces haría cumplir que todas las anulaciones usan override.


25
2018-04-26 14:38



Hay dos cosas que puedes hacer.

En primer lugar, Clang 3.5 y superior tienen una -Winconsistent-missing-override advertencia (desencadenada por -Wall) Esto no funciona para su ejemplo, pero solo si agrega un void foo() override {} a class B y no en class C. Lo que realmente quieres es -Wmissing-override, para localizar a todos los desaparecidos override, no solo los inconsistentemente perdidos. Actualmente no se proporciona, pero es posible que se queje en la lista de correo de Clang y quizás lo agreguen.

Segundo, tu usas El truco de Howard Hinnant a temporalmente añadir final a la función miembro de la clase base y recompilar. El compilador localizará todas las demás clases derivadas que intenten anular el virtual función de miembro base. A continuación, puede corregir los que faltan. Es un poco más trabajo y requiere una nueva comprobación frecuente cuando se expande la jerarquía de su clase.


10
2018-03-19 20:15



El problema que veo con -Werror=suggest-override es que no te permite escribir lo siguiente:

void f() final {...}

Aunque hay un implícito override aquí. los -Werror=suggest-override no ignora esto (como debería, ya que override es redundante en este caso)

Pero es más complicado que eso ... Si escribes

virtual void f() final {...}

Significa algo completamente diferente a

virtual void f() override final {...}

¡El primer caso no necesita anular nada! El segundo lo hace

Por lo tanto, supongo que la verificación GCC se implementa de esta manera (es decir, a veces se acepta la redundancia override) para que el último caso sea el correcto. Pero esto no funciona bien, p. con clang-tidy, que eliminará correctamente la anulación cuando final sea suficiente (pero la compilación de GCC fallará ...)


2
2018-03-23 17:24



GCC y Clang están cubiertos por otras respuestas. Esto es lo mismo para VC ++ de mi otra respuesta:

A continuación se muestran los números de advertencia relevantes en VC ++:

C4263 (level 4) 'function': member function does not override any base class virtual member function
C4266 (level 4) 'function': no override available for virtual member function from base 'type'; function is hidden

Para habilitar estas dos advertencias, puede usar una de las siguientes opciones:

  1. Establezca el nivel de advertencia en 4 en la configuración del proyecto y luego desactive las advertencias que no desea. Esta es mi manera preferida. Para deshabilitar las advertencias de Nivel 4 no deseadas, vaya a la configuración del proyecto> C / C ++> Avanzado y luego ingrese los números de advertencia en el cuadro Deshabilitar advertencias específicas.
  2. Habilite las dos advertencias anteriores usando el código.

    #pragma warning(default:4263)
    #pragma warning(default:4266)
    
  3. Habilite las dos advertencias anteriores en la configuración del proyecto> C / C ++> Línea de comando y luego ingrese / w34263 / w34266. La opción Here / wNxxxx significa habilitar las advertencias xxxx en el Nivel N (N = 3 es el nivel predeterminado). También puede hacer / wdNxxxx que deshabilita la advertencia xxxx en el nivel N.


-1
2017-12-12 21:29