Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
shpora_oop.doc
Скачиваний:
1
Добавлен:
01.03.2025
Размер:
258.05 Кб
Скачать

34.Виртуальные функции.

Прежде чем коснуться самого применения виртуальных функций, необ-

ходимо рассмотреть такие понятия, как раннее и позднее связывание.

Во время раннего связывания вызывающий и вызываемый методы связы-

ваются при первом удобном случае, обычно при компиляции.

При позднем связывании вызываемого и вызывающего методов они не

могут быть связаны во время компиляции. Поэтому реализован специальный механизм, который определяет, как будет происходить связывание вызываемого и вызывающего методов, когда вызов будет сделан фактически. Очевидно, что скорость и эффективность при раннем связывании выше, чем при использовании позднего связывания. В то же время позднее связывание обеспечивает некоторую универсальность процесса связывания. Один из основных принципов объектно-ориентированного программирования предполагает использование идеи «один интерфейс – множество методов реализации». Эта идея заключается также в том, что базовый класс обеспечивает все элементы, которые производные классы могут непосредственно использовать, плюс набор функций, которые производные классы должны реализовать путем их переопределения. Наряду с механизмом перегрузки функций это достигается использованием виртуальных (virtual) функций. Виртуальная функция

– это функция, объявленная с ключевым словом virtual в базовом классе и переопределенная в одном или нескольких производных от этого классах. При вызове объекта базового или производных классов динамически (во время выполнения программы) определяется, какую из функций требуется вызвать, основываясь на типе объекта. Преимущество применения виртуальных методов заключается в том, что при этом используется именно механизм позднего связывания, который допускает обработку объектов, тип которых неизвестен во время компиляции.

#include "iostream"

#include "iomanip"

using namespace std;

#include "string.h"

class grup // базовый класс

{ protected:

char *fak; // наименование факультета

long gr; // номер группы

public:

grup(char *FAK,long GR) : gr(GR)

{ if (!(fak=new char[20]))

{ cout<<"ошибка выделения памяти"<<endl;

return;

}

strcpy(fak,FAK);

}

~grup()

{ cout << "деструктор класса grup " << endl;

delete fak;

}

virtual void see(void); // объявление виртуальной функции

};

class stud : public grup // производный класс

{ char *fam; // фамилия

int oc[4]; // массив оценок

public:

stud(char *FAK,long GR,char *FAM,int OC[]): grup(FAK,GR)

{ if (!(fam=new char[20]))

{ cout<<"ошибка выделения памяти"<<endl;

return;

}

strcpy(fam,FAM);

for(int i=0;i<4;oc[i]=OC[i++]);

}

~stud()

{ cout << "деструктор класса stud " << endl;

delete fam;

}

void see(void);

};

void grup::see(void) // описание виртуальной функции

{ cout << fak << gr << endl;}

void stud::see(void) //

{ grup ::see(); // вызов функции базового класса

cout <<setw(10) << fam << " ";

for(int i=0; i<4; cout << oc[i++]<<’ ’);

cout << endl;

}

int main()

{ int OC[]={4,5,5,3};

grup gr1("факультет 1",123456), gr2("факультет 2",345678), *p;

stud st("факультет 2",150502,"Иванов",OC);

p=&gr1; // указатель на объект базового класса

p->see(); // вызов функции базового класса объекта gr1

(&gr2)->see(); // вызов функции базового класса объекта gr2

p=&st; // указатель на объект производного класса

p->see(); // вызов функции производного класса объекта st

return 0;

}

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]