Информатика и технология программирования

         

Виртуальные функции - как элемент " отложенного" проектирования


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

Рассмотрим в качестве примера фрагмент класса двоичного файла, в котором обработка ошибок открытия файла вынесена за пределы класса - в производный класс.


// Класс двоичных файлов с " отложенной" функцией обработки ошибок


&#35include &#60fstream.h&#62
typedef int BOOL;
typedef long FPTR; // Тип - указатель в файле


class BinFile : public fstream
{
public:
BOOL Open(char *); // Открыть существующий


virtual int OnError(char *s)
{return NULL}; // Обработка ошибок открытия


// по умолчанию - отказ от дальнейших


}; // попыток открыть файл


BOOL BinFile::Open(char * s)
{
char ss[80];
strcpy(ss,s);
while (1)
{
open(ss,ios::in | ios::out | ios::binary);
if (good()) return 1;
if (!OnError(ss)) // Виртуальная функция в производном классе


return 0; // ищет другое подходящее имя файла


}
return 1;
}

Виртуальная функция в производном классе должна выполнить конкретный диалог, содержание которого в базовом классе не раскрывается. В качестве результата она должна загрузить строку в массив - имя нового файла. Если " пользователь" производного класса предполагает продолжать диалог, он может это сделать например, так


class MyFile : public BinFile
{
public:
virtual int OnError(char *s)
{
cout &#60&#60 " не могу открыть файл " &#60&#60 s &#60&#60 endl;
cout &#60&#60 " введите еще (CR-отказ):" ;
cin &#62&#62 s;
if (s[0]==0) return 0;
return 1;
}
};



Содержание раздела