virtuales sencillos programacion polimorfismo orientada objetos herencia funciones ejemplos constructores c++ warnings overloading virtual hidden

sencillos - c++ alerta de función virtual sobrecargada por clang?



polimorfismo java (4)

clang emite una advertencia al compilar el siguiente código:

struct Base { virtual void * get(char* e); // virtual void * get(char* e, int index); }; struct Derived: public Base { virtual void * get(char* e, int index); };

La advertencia es:

warning: ''Derived::get'' hides overloaded virtual function [-Woverloaded-virtual]

(dicha advertencia debe ser habilitada por supuesto).

No entiendo por qué. Tenga en cuenta que al eliminar la misma declaración en Base, se cierra la advertencia. Según tengo entendido, dado que las dos funciones get () tienen diferentes firmas, no puede haber ninguna ocultación.

Está sonando bien? ¿Por qué?

Tenga en cuenta que esto es en MacOS X, que ejecuta una versión reciente de Xcode.

clang --version Apple LLVM version 5.0 (clang-500.1.74) (based on LLVM 3.3svn)

Actualización: el mismo comportamiento con Xcode 4.6.3.


Advertencia significa que no habrá función void * get (char * e) en el ámbito de la clase Derivada, porque la ocultará otro método con el mismo nombre. El compilador no buscará la función en las clases base si la clase derivada tiene al menos un método con el nombre especificado, incluso si tiene otros argumentos.

Este código de muestra no se compilará:

class A { public: virtual void Foo() {} }; class B : public A { public: virtual void Foo(int a) {} }; int main() { B b; b.Foo(); return 0; }


Esta advertencia está ahí para evitar el ocultamiento accidental de las sobrecargas cuando se pretende anular. Considera un ejemplo ligeramente diferente:

struct chart; // let''s pretend this exists struct Base { virtual void* get(char* e); }; struct Derived: public Base { virtual void* get(chart* e); // typo, we wanted to override the same function };

Como es una advertencia, no significa necesariamente que sea un error, pero podría indicar una. Por lo general, tales advertencias tienen un medio para desactivarlos al ser más explícitos y dejar que el compilador sepa que usted tenía la intención de escribir. Creo que en este caso puedes hacer lo siguiente:

struct Derived: public Base { using Base::get; // tell the compiler we want both the get from Base and ours virtual void * get(char* e, int index); };


Otra forma de desactivar la advertencia manteniendo intacta la interfaz pública struct sería:

struct Derived: public Base { virtual void * get(char* e, int index); private: using Base::get; };

Esto no permite que un consumidor de Derived llame a Derived::get(char* e) mientras silencia la advertencia:

Derived der; der.get("", 0); //Allowed der.get(""); //Compilation error


La solución de R. Martinho Fernandes es perfectamente válida si realmente desea llevar el método get() tomando un único argumento char * en el alcance Derived .

En realidad, en el fragmento que proporcionó, no hay necesidad de métodos virtuales (ya que Base y Derivados no comparten ningún método con la misma firma).

Suponiendo que realmente hay una necesidad de polimorfismo, el comportamiento de ocultamiento podría no obstante ser lo que se pretende. En este caso, es posible desactivar localmente la advertencia de Clang, con el siguiente pragma:

#pragma clang diagnostic push #pragma clang diagnostic ignored "-Woverloaded-virtual" // Member declaration raising the warning. #pragma clang diagnostic pop