зации не возникает никаких проблем,
рис. 14.4). При реали зации не возникает никаких проблем, потому что мы принимаем, что все указатели представляются одинаково независимо от указуемого типа.

Важно обратить внимание на то, что после присваивания указателя компилятор больше не имеет никакой информации относительно типа указуемого объекта. Таким образом, у него нет возможности привязать вызов
Base_Ptr- >virtual_proc();
к правильной подпрограмме, и следует выполнить динамическую диспетчеризацию. Аналогичная ситуация возникает, когда используется ссылочный параметр, как было показано выше.
Эта ситуация может внести путаницу, так как программисты обычно не делают различия между переменной и указуемым объектом. После следующих операторов:
inti1 = 1;
int i2 = 2;
int *p1 = &i1; // p1 ссылается на i1
int *p2 = &i2; // p2 ссылается на i2
p1 = p2; // p1 также ссылается на i2
i1 = i2; // i1 имеет то же самое значение, что и i2
вы ожидаете, что i1 == i2 и *р1 ==*р2; это, конечно, правильно, пока типы в точности совпадают, но это неверно для присваивания производного класса базовому классу из-за усечения. При использовании наследования вы должны помнить, что указуемый объект может иметь тип, отличный от типа указуемого объекта в объявлении указателя.
Есть одна западня в семантике динамического полиморфизма языка C++: если вы посмотрите внимательно, то заметите, что обсуждение касалось диспетчеризации, относящейся к замещенной виртуальной подпрограмме. Но в классе могут также быть и обычные подпрограммы, которые замещаются:
Base_Ptr = Derived_Ptr;
Base_Ptr->virtual_proc(); // Диспетчеризуется по указанному типу
Base_Ptr->ordinary_proc(); // Статическое связывание с базовым типом!!
Существует различие в семантике между двумя вызовами: вызов виртуальной подпрограммы диспетчеризуется во время выполнения в соответствии с типом указуемого объекта, в данном случае Derived_Class; вызов обычной подпрограммы связывается статически во время компиляции в соответствии с типом указателя, ъ данном случае Base_Class.