Що ж потрібно зробити для того, щоб досягнути бажаного результату - щоб при виклику функції Fun(X) відбувався виклик базового методу, а при Fun(Y) - виклик похідного методу? Саме для цього і використовуються віртуальні функції. Перед описом функції print() в базовому класі ставимо ключове слово virtual. Це означає, що в функції Fun зв'язування виклику функції print() з її тілом буде відбуватися динамічно ("пізнє зв'язування") на етапі виконання програми. Тому і будуть працювати різні методи для різних вхідних даних. В цьому і полягає механізм віртуальних функцій. Віртуальну функцію можна викликати і невіртуально, якщо вказати кваліфікатор класу.
?
#include <iostream.h>
#include <conio.h>
class Base // базовий клас
{
public:
virtual void print(); // віртуальна функція
};
void Base::print()
{
cout<<endl<<"Base-print"<<endl; // базовий метод
}
class Derive:public Base // похідний клас
{
public:
void print();
};
void Derive::print()
{
cout<<endl<<"Derive-print"<<endl; // перевизначений метод
}
void Fun(Base &M) // функція, що отримує об'єкт базового класу по посиланю
{
M.print(); // відбувається "пізнє" (динамічне) зв'язування, виклик віртуальної функції
}
int main(int argc, char* argv[])
{
Base X; // об'єкт базового класу
Derive Y; // об'єкт похідного класу
X.print(); // виклик базового методу
Y.print(); // виклик похідного методу
cout<<endl;
Fun(X); // працює базовий метод
Fun(Y); // працює похідний метод !!!
cout<<endl;
Y.Base::print(); // невіртуальний виклик віртуальної функції, статичний виклик
getch();
return 0;
}