Итак, допустим, у меня есть цепочка классов, где каждый класс является производным от класса перед ним.По какой-то причине им всем нравится использовать одно и то же имя для некоторой функции-члена.Вроде как:
class C1 { public: void f() { cout<<"C1"; }; };
class C2 : public C1 { public: void f() { cout<<"C2"; }; };
class C3 : public C2 { public: void f() { cout<<"C3"; }; };
Очевидно, что если я просто объявлю некоторые объекты, а затем вызову функцию f из них, все вызовут функцию, связанную с их соответствующим типом объекта:
C1 c1; c1.f(); // prints C1
C2 c2; c2.f(); // prints C2
C3 c3; c3.f(); // prints C3
Теперь, если я объявлю некоторые указатели на объекты, а затем вызову функцию f из них, все вызовут функцию, связанную с их соответствующим типом указателя:
C1* p1 = &c1; p1->f(); // prints C1
C1* p2 = &c2; p2->f(); // prints C1
C1* p3 = &c3; p3->f(); // prints C1
C2* p4 = &c2; p4->f(); // prints C2
C2* p5 = &c3; p5->f(); // prints C2
C3* p6 = &c3; p6->f(); // prints C3
Все это супер.Я либо вызываю функцию, связанную с типом объекта, либо вызываю функцию, связанную с типом указателя ...
Или, конечно, я могу сделать функцию «виртуальной».Тогда, если я вызову функцию из какого-либо объекта, я не получу никаких изменений в поведении;однако, если я вызову функцию из некоторого указателя, то я не просто вызову функцию для типа указателя, я на самом деле вызову функцию для типа объекта, на который указывает указатель.Пока все хорошо.
Я даже могу перейти на виртуальную середину через цепочку наследования.Допустим, я поставил виртуальный перед функцией f внутри класса C2.Теперь функция сделана виртуальной (т. Е. При вызове из указателей она использует указатель на тип объекта вместо типа указателя для разрешения вызова функции) не только для своего собственного класса, но и для всех будущих классов, которые
Мой вопрос заключается в следующем: после того, как функция была объявлена виртуальной (в какой-то момент в цепочке наследования), она может быть когда-либо возвращена обратно не виртуальной (далее по цепочкенаследование)?
Для пояснения: когда я говорю «вернуться к не виртуальному поведению», я имею в виду, что когда я вызываю функцию из указателя, она будет использовать тип указателя для разрешения вызова функции (а нетип объекта, на который указывает указатель).