2011-06-03 29 views
5

consideran este programa de demostración:métodos virtuales puros C++

#include <stdio.h> 

class Base 
{ 
public: 
    virtual int f(int) =0; 
    virtual int f(){ return f(0); } 

    virtual ~Base(){ } 
}; 

class Derived : public Base 
{ 
public: 
    int f(int i) 
    { 
     return (10 + i); 
    } 
}; 

int main(void) 
{ 
    Derived obj; 
    printf("%d\n", obj.f(1)); // This works, and returns 11 
    printf("%d\n", obj.f()); // Adding this line gives me the error listed below 
} 

Lo que me da el siguiente error de compilación:

virtualfunc.cpp: In function ‘int main()’: 
virtualfunc.cpp:25:26: error: no matching function for call to ‘Derived::f()’ 
virtualfunc.cpp:15:9: note: candidate is: virtual int Derived::f(int) 

Mi esperanza era que una llamada a obj.f() resultaría en una llamada a Base::obj.f() desde la clase derivada no la define, lo que daría como resultado una llamada a Derived::obj.f(0) según la definición en la clase Base.

¿Qué estoy haciendo mal aquí? ¿Hay alguna manera de lograr esto? Específicamente, me gustaría llamar a obj.f() para devolver 10.

(También tenga en cuenta que me doy cuenta de que podría usar un argumento predeterminado para resolver esto, pero este código es simplemente un ejemplo conciso de mi problema, así que por favor 'dime que use argumentos predeterminados.)

Gracias.

+1

La función 'f' en' Derived' 'oculta' las otras funciones, definidas en' Base'. Es por eso que obtiene este error –

+2

engañado de http://stackoverflow.com/questions/585913/c-member-function-virtual-override-and-overload-at-the-same-time –

+1

@Kiril Kirov, usted gana - - Si quiere responder esto, lo marcaré como correcto. Agregando explícitamente 'using Base :: f;' en la definición de clase Derivada se solucionó. ¡Gracias! – jedwards

Respuesta

3

La razón es, que la define f (en Derived) hides los f funciones de la clase Base. La solución es agregar using.De esta manera:

class Derived : public Base 
{ 
public: 
    int f(int i) 
    { 
     return (10 + i); 
    } 

// vvvvvvvvvvvvvv 
    using Base::f; 
}; 
8

El problema con el que te encuentras es ortogonal a las funciones virtuales puras y tiene que ver con cómo la resolución de nombres de C++ en las jerarquías de clases.

Cuando se escribe

obj.f(); 

C++ trata de buscar una función llamada f por lo que sabe lo que desea llamar. Como obj es del tipo Derived, comienza dentro de Derived y busca una función llamada f. Termina encontrando Derived::f(int), y aunque esta función toma un argumento, C++ cree que este es el método que está tratando de llamar y, por lo tanto, deja de buscar. El compilador se da cuenta de que está tratando de invocarlo sin parámetros, lo que le da el error sobre la llamada a la función.

Para solucionar esto, debe decirle al compilador de C++ que también debe intentar buscar la función Base::f(), que está incluida en la clase base. Para ello, se puede cambiar la definición de Derived de la siguiente manera:

class Derived : public Base 
{ 
public: 
    int f(int i) 
    { 
     return (10 + i); 
    } 

    using Base::f; 
}; 

Esta línea using Base::f dice C++ que se debe tratar en funciones Base nombrados f como si fueran parte de Derived. De esta forma, cuando el compilador intenta buscar una función llamada f, encuentra tanto Derived::f(int) como Base::f(). La llamada tendrá éxito porque el compilador puede darse cuenta de que está intentando llamar al Base::f() con el código que ha enumerado.

Espero que esto ayude!

+2

Esta explicación ayuda mucho - muchas gracias. – jedwards

3

La definición de f(int) en la clase derivada oculta el nombre Base::f que no anuló. Todo lo que necesita hacer es Para mostrar esto escribiendo using Base::f; en la clase derivada:

class Derived : public Base 
{ 
public: 

    using Base::f; //note this line! 

    int f(int i) 
    { 
     return (10 + i); 
    } 
}; 
+0

No es un mecanismo virtual solo para los punteros, referencias? – Mahesh

+0

@Mahesh: Esto no tiene nada que ver con el mecanismo virtual, porque él está utilizando el objeto de tipo derivado. – Nawaz

+0

No veo ningún uso específico de virtual aquí. – Mahesh

Cuestiones relacionadas