Почему динамическое связывание может переопределить скрытие имени в 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 аргументов
Не могли бы вы помочь мне объяснить это явление? В частности, может ли динамическое связывание переопределить скрытие имени, как я предположил? Если так, почему переопределение завершается ошибкой, если указатель указывает на производный класс? Спасибо.
1 ответ
Поиск имени (и разрешение перегрузки) происходит во время компиляции.
Дано bp->fcn
, если тип bp
является Base*
, поиск имени будет изучать сферу Base
а затем найти имя Base::fcn
, Дело в том, что bp
указывает на объект Derived
не включает в себя, ни сфера Derived
а потом Derived::fcn
, Динамическая отправка происходит во время выполнения, если Derived
имеет переопределенный Derived::fcn()
он будет вызван во время выполнения.
Если тип bp
является Derived*
, поиск имени будет изучать сферу Derived
а затем найти имя Derived::fcn
затем имя поиска останавливается, область действия Base
больше не будет рассматриваться; имя скрывается