C ++ полиморфизм, перегрузка и наследование - PullRequest
2 голосов
/ 31 марта 2020

Учитывая

#include <iostream>
#include <string>

using std::cout;
using std::endl;

class A
{
public:
    virtual int a() const = 0;
    virtual int a(const int i) const = 0;
};

class B : public A
{
public:
    virtual int a() const { return A::a(0); }    
};

class C : public B
{
public:
    virtual int a(const int i) const { return i; }
};


int main()
{
    C c;
    cout << c.a() << endl;
    cout << c.a(1) << endl; 
}

Я не тестировал с разными компиляторами, но у меня есть следующие ошибки:

main.cpp:31:17: error: no matching function for call to ‘C::a()’
     cout << c.a() << endl;
                 ^
main.cpp:24:17: note: candidate: virtual int C::a(int) const
     virtual int a(const int i) const { return i; }
                 ^
main.cpp:24:17: note:   candidate expects 1 argument, 0 provided

Я действительно не понимаю, почему, я ожидал, что класс C может получить доступ по адресу B::a().

Кажется, что разрешение C.a() определяется как C.a(int). В основном виртуальный метод из B не виден. Кто-нибудь знает почему?

РЕДАКТИРОВАТЬ

Идея выглядит примерно так: A как "интерфейс", B как "абстрактный класс", C "конкретный класс"

РЕШЕНИЕ

То, чего я пытался достичь, возможно с using A::a using B::a и изменением вызова B::a() с A::a(0) на a(0).

Как в примере здесь предоставлено songyuanyao

1 Ответ

1 голос
/ 31 марта 2020

C::a скрывает B::a. Когда имя a находится в области видимости класса C, поиск имени останавливается, дальнейшие области, включая класс B, проверяться не будут.

name поиск просматривает области, как описано ниже, пока не найдет хотя бы одну декларацию любого вида, и в этот момент поиск останавливается и дальнейшие области не проверяются.

Вы можете добавить using, чтобы ввести B::a в область действия C.

class C : public B
{
public:
    using B::a;
    virtual int a(const int i) const { return i; }
};
...