Почему динамическая привязка может переопределить скрытие имен в C++?

Я узнал, что внутренние имена скрывают внешние имена (поэтому перегрузка не выходит за рамки), потому что поиск имени предшествует сопоставлению типов. Поэтому я пишу следующий код C++, чтобы поиграть с этим правилом:

class Base {
public:
    virtual void fcn() {}
};
class Derived : public Base {
public:
    void fcn(std::string s) {}
};

Base* bp = new Derived;
bp->fcn();
delete bp;

Согласно правилу скрытия, функция Derived::fcn(std::string) должна скрывать Base::fcn(). Но приведенный выше код компилируется и работает правильно вопреки правилу. Означает ли это, что динамическая привязка может переопределить скрытие имени в C++? Дело в том, что если я изменю тип bp на Derived*, правило скрытия вступит в силу, произнося ошибку компиляции:

'Derived::fcn': функция не принимает 0 аргументов

Не могли бы вы помочь мне объяснить явление? В частности, может ли динамическая привязка переопределить скрытие имени, как я предполагал? Если да, то почему переопределение не работает, если указатель указывает на производный класс? Спасибо.


person user5280911    schedule 20.02.2019    source источник
comment
Скрытие имени не делает функцию недоступной, только ее имя. Например, это тоже совершенно законно: Derived d; d.Base::fcn();   -  person Ben Voigt    schedule 20.02.2019


Ответы (1)


Поиск имени (и разрешение перегрузки) происходит во время компиляции.

Учитывая bp->fcn, если тип bp равен Base*, поиск имени проверит область действия Base, а затем найдет имя Base::fcn. Тот факт, что bp указывает на объект Derived, не затрагивает ни область действия Derived, ни затем Derived::fcn. Динамическая диспетчеризация происходит во время выполнения, если Derived имеет переопределенный Derived::fcn(), он будет вызываться во время выполнения.

Если тип bp равен Derived*, поиск имени проверит область Derived, а затем найдет имя Derived::fcn, затем поиск имени остановится, область Base больше не будет проверяться; происходит сокрытие имени.

person songyuanyao    schedule 20.02.2019
comment
Великолепно! Большое спасибо! - person user5280911; 20.02.2019