Почему динамическое связывание может переопределить скрытие имени в C ++? - PullRequest
0 голосов
/ 20 февраля 2019

Я узнал, что внутренние имена скрывают внешние имена (поэтому перегрузка не пересекает область видимости), потому что поиск имени идет перед сопоставлением типов.Поэтому я пишу следующий код 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Аргументы

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

1 Ответ

0 голосов
/ 20 февраля 2019

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

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...