Прежде чем пытаться описать семантику любой инструкции C ++, вам необходимо вернуться к самым фундаментальным концепциям C ++ (которые являются сложным вариантом фундаментальных концепций C): C ++ - это скомпилированный язык со статическимнабрав .
Как и в C, в C ++ имена ищутся и связываются во время компиляции : любое используемое имя должно ссылаться на видимое объявление.Единственные имена, которые могут быть найдены компилятором, это имена в классе, обозначенном выражением.(Выражения являются синтаксическими конструкциями, они существуют во время компиляции .)
В языке со статической типизацией типы выражений являются статическими и вычисляются внутри каждой функции в соответствии ск объявлениям.
C ++ также поддерживает динамический полиморфизм через виртуальные функции;это не делает язык динамически типизированным;основы неизменны: у каждого выражения есть тип, определяемый применением правил на основе его синтаксиса и видимых объявлений (видимых имен объектов, функций и т. д.).
С динамическим полиморфным типомполиморфный объект (объекты существуют в время выполнения ), то есть тип, который был создан (имя класса конструктора, который работал для создания объекта) определяет, какое тело функции являетсявызывается виртуальным вызовом .Иногда это называется поздним связыванием.
Позднее связывание здесь не является проблемой в вашем плохо сформированном коде, который даже не компилируется, не запускается и не вызывает какую-либо функцию во время выполнения любогополиморфный объект:
obj->f3(); // Error (though was expecting LB since f3 is virtual)
Когда obj
имеет тип указателя obj->something
совпадает с (*obj).something
;obj
- локальная переменная, определенная как
A* obj = (...something not relevant for the argument...);
, поэтому obj
имеет тип A*
, а *obj
имеет тип A
, который является классом, определенным как:
class A
{
public:
void f1() {cout<<"A::f1"<<endl;}
virtual void f2() {cout<<"A::f2"<<endl;}
};
Нет объявления какого-либо члена f3
, видимого в классе, обозначенном выражением *obj
. Таким образом, вызов неверно сформирован. Он недействителен во время компиляции, и компилятор отклоняет его.
И это весь соответствующий анализ этого плохо сформированноголиния.Остальное не имеет значения в статически типизированном языке.Производные классы, не названные в релевантном коде (который является просто объявленным типом obj
и выражением, определяющим, где выполняется поиск по имени, *obj
), не имеют значения.Это сущность статической типизации.
Кроме того, создание достоверности кода зависит от других классов, не имеющих прямого имени (классов, которые могут быть типом объекта, созданного во время выполнения,какое-то выражение относится к) сделает невозможным обнаружение даже простой опечатки во время компиляции.