Полиморфизм –это механизм, позволяющий использовать один и тот же интерфейс для объектов базовых и производных классов. В С++ полиморфизм реализуют с помощью виртуальных функций.
Виртуальная функция (virtual function) является функцией-членом класса. Она объявляется внутри базового класса и переопределяется в производном классе.
Виртуальная функция объявляется при помощи спецификатора virtual, указываемого перед типом возвращаемого функцией значения. После того, как Вы объявили функцию виртуальной, ее можно переопределить только в производном классе. Замещающие функции должны иметь тот же список параметров.
Когда в виртуальной функции базового класса отсутствует значимое действие, в реализации любого производного класса эта функция обязательно должна переопределяться. Для реализации этого положения в С++ поддерживаются чисто виртуальные функции (pure virtual function). Для чисто виртуальных функций используется такая общая форма прототипа:
virtual type Name(parameters) = 0;
Ключевым моментом этого объявления является приравнивание функции нулю. Это сообщает компилятору, что в базовом классе не существует тела функции.
Если класс содержит хотя бы одну чисто виртуальную функцию, то о нем говорят как об абстрактном классе. Абстрактный класс может быть только наследуемым, поскольку в нем содержится, по крайней мере, одна функция, у которой отсутствует тело, то есть нельзя создавать объекты такого класса.
Если объявляется указатель на объект, то при использовании перегрузки функций, типуказателя определяет, из какого класса вызывается функция. При использовании виртуальныхфункций, класс вызываемой функции определяется не по типу указателя, а по типу объекта, адрес которого хранит этот указатель.
Пример : Классы, описывающие точки и окружности.
#include <iostream>
#include <conio.h>
#include <windows.h>
#define _USE_MATH_DEFINES
#include <cmath>
using namespace std;
// Класс, описывающий точку:
class CPoint
{
protected:
int x,y; // координаты точки
public:
// Конструктор:
CPoint(int _x=320, int _y=240)
{ x = _x; y = _y; }
int GetX() {return x;}
virtual double Length() //Виртуальная функция возвращающая длину.
// Для точки - длинна радиус вектора:
{
return sqrt((double)(x*x+y*y));
}
};
// Класс, описывающий окружность (производный от класса CPoint):
class CCircle : public CPoint
{
int r; // радиус окружности
public:
CCircle(){r=2;}
// Основной конструктор:
CCircle(int _x, int _y,int _r):
CPoint (_x, _y) // Явный вызов конструктора базового класса
{r = _r;}
double Length() {return 2*M_PI*r;} // длина окружности
};
// Пример использования классов:
int main()
{
//Настройки шрифтов и региональных стандартов:
if(SetConsoleCP(1251)==0)
//проверка правильности установки кодировки символов для ввода
{
cerr<<"Fialed to set codepage!"<<endl;
/* если не удалось установить кодовую страницу, вывод сообщения об ошибке */
}
if(SetConsoleOutputCP(1251)==0)//тоже самое для вывода
{
cerr<<"Failed to set OUTPUT page!"<<endl;
}
CPoint** ptr = new CPoint*[5]; /* помните, что указатель на объект производного класса является одновременно и указателем на объект базового класса */
// создаем несколько объектов:
ptr[0] = new CPoint (100, 100);
ptr[1] = new CCircle(200,150, 10);
ptr[2] = new CPoint (100,200);
ptr[3] = new CCircle(200,250,10);
ptr[4] = new CPoint(100,300);
/* такого типа цикл можно написать только при использовании виртуальных функций: */
for (int i=0; i<5; i++)
cout<<"Длинна объекта "<<ptr[i]->Length()<<endl;
// одним оператором обрабатываем объекты разных типов