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]
(la advertencia mencionada debe estar habilitada, por supuesto).
No entiendo por qué. Tenga en cuenta que descomentar la misma declaración en Base cierra la advertencia. Tengo entendido que dado que las dos funciones get () tienen firmas diferentes, no se puede ocultar.
¿Es cierto clang? ¿Por qué?
Tenga en cuenta que esto está 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: mismo comportamiento con Xcode 4.6.3.
get
miembro de la función con un solo argumento en un objeto de tipo estáticoDerived
. Sin la declaración using, lo mismo conduciría a un error de compilación.Otra forma de deshabilitar la advertencia manteniendo intacta la interfaz pública de la estructura 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
llameDerived::get(char* e)
mientras silencia la advertencia:Derived der; der.get("", 0); //Allowed der.get(""); //Compilation error
fuente
get
método de clase de la base !La solución de R. Martinho Fernandes es perfectamente válida si realmente desea llevar el
get()
método tomando un solo argumento char * enDerived
alcance.En realidad, en el fragmento que proporcionó, no hay necesidad de métodos virtuales (ya que Base y Derived no comparten ningún método con la misma firma).
Suponiendo que realmente existe una necesidad de polimorfismo, el comportamiento de ocultación podría ser, no obstante, lo que se pretende. En este caso, es posible deshabilitar 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
fuente
const
del método heredado y el sonido metálico estuvo bien todo el tiempo. En caso de duda, confíe en el compilador. Cuando dude del compilador, confíe en el compilador. :) +1 por darme tanto lo que buscaba como lo que necesitaba.Advertencia significa que no habrá función void * get (char * e) en el alcance de la clase Derived, porque está oculta por otro método con el mismo nombre. El compilador no buscará funciones 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; }
fuente
b.Foo();
. Solo necesitas escribirb.A::Foo();
.