c++ - ¿Por qué una función anulada en la clase derivada oculta otras sobrecargas de la clase base?




2 Answers

Las reglas de resolución de nombres dicen que la búsqueda de nombres se detiene en el primer ámbito en el que se encuentra un nombre coincidente. En ese punto, las reglas de resolución de sobrecarga se activan para encontrar la mejor coincidencia de funciones disponibles.

En este caso, gogo(int*) se encuentra (solo) en el alcance de la clase Derivada, y como no hay una conversión estándar de int a int *, la búsqueda falla.

La solución es traer las declaraciones de Base a través de una declaración de uso en la clase Derivada:

using Base::gogo;

... permitiría que las reglas de búsqueda de nombres encontraran a todos los candidatos y, por lo tanto, la resolución de sobrecarga continuaría como esperaba.

c++ polymorphism override

Considere el código:

#include <stdio.h>

class Base {
public: 
    virtual void gogo(int a){
        printf(" Base :: gogo (int) \n");
    };

    virtual void gogo(int* a){
        printf(" Base :: gogo (int*) \n");
    };
};

class Derived : public Base{
public:
    virtual void gogo(int* a){
        printf(" Derived :: gogo (int*) \n");
    };
};

int main(){
    Derived obj;
    obj.gogo(7);
}

Conseguí este error:

>g++ -pedantic -Os test.cpp -o test
test.cpp: In function `int main()':
test.cpp:31: error: no matching function for call to `Derived::gogo(int)'
test.cpp:21: note: candidates are: virtual void Derived::gogo(int*) 
test.cpp:33:2: warning: no newline at end of file
>Exit code: 1

Aquí, la función de la clase Derivada está eclipsando todas las funciones del mismo nombre (no la firma) en la clase base. De alguna manera, este comportamiento de C ++ no se ve bien. No polimorfo.




La ocultación de nombres tiene sentido porque evita las ambigüedades en la resolución de nombres.

Considere este código:

class Base
{
public:
    void func (float x) { ... }
}

class Derived: public Base
{
public:
    void func (double x) { ... }
}

Derived dobj;

Si Base::func(float) no estuviera oculto por Derived::func(double) en Derived, llamaríamos a la función de clase base al llamar a dobj.func(0.f) , aunque un float puede ser promovido a doble .

Referencia: http://bastian.rieck.ru/blog/posts/2016/name_hiding_cxx/




Related