Чисто виртуальные функции. Абстрактный базовый класс
Поможем в ✍️ написании учебной работы
Поможем с курсовой, контрольной, дипломной, рефератом, отчетом по практике, научно-исследовательской и любой другой работой

Когда виртуальная функция не переопределена в производном классе, то при вызове ее в объекте производного класса вызывается версия из базового класса. Однако во многих случаях невоз­можно ввести содержательное определение виртуальной функции в базовом классе. Например, при объявлении базового класса figure в предыдущем примере определение функции show_area() не несет никакого содержания. Она не вычисляет и не выводит на экран площадь объекта какого- либо типа. Имеется два способа действий в подобной ситуации. Первый, подобно предыдущему примеру, заключается в выводе какого-нибудь предупреждающего сообщения. Хотя такой подход полезен в некоторых ситуациях, он не является универсальным. Могут быть такие виртуальные функции, которые обязательно должны быть определены в производных классах, без чего эти производные классы не будут иметь никакого значения. Например, класс triangle бесполезен, если не определена функция show_агеа(). В таких случаях необходим метод, гарантирующий, что производные классы действительно определят все необходимые функции. Язык С++ предлагает в качестве решения этой проблемы чисто виртуальные функции.

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

virtual тип имя_функции(список параметров) = 0;

Здесь тип обозначает тип возвращаемого значения, а имя_функции является именем функции. На­пример, следующая версия функции show_area() класса figure является чисто виртуальной функцией.

class figure {
double х, у;
public:
void set_dim(double i, double j=0) {
x = i;
y = j;
}
virtual void show_area() = 0; // чисто виртуальная
};

При введении чисто виртуальной функции в производном классе обязательно необходимо опре­делить свою собственную реализацию этой функции. Если класс не будет содержать определения этой функции, то компилятор выдаст ошибку. Например, если попытаться откомпилировать сле­дующую модифицированную версию программы figure, в которой удалено определение функции
snow_area() из класса circle, то будет выдано сообщение об ошибке:

/* Данная программа не компилируется, поскольку класс circle не переопределил show_агеа() */
#include <iostream.h>
class figure {
protected:
double x, y;
public:
void set_dim(double i, double j) {
x = i;
у = j;
}
virtual void show_area() = 0; // pure
};
class triangle: public figure {
public:
void show_area() {
cout << "Triangle with height ";
cout << x << " and base " << y;
cout << " has an area of ";
cout << x * 0.5 * у << ". \ n";
}
};
class square: public figure {
public:
void show_area() {
cout << "Square with dimensions ";
cout << x << "x" << y;
cout << " has an area of ";
cout << x * у << " . \n";
}
};
class circle: public figure {
// определение show_area() отсутствует и потому выдается ошибка
};
int main ( )
{
figure *р; // создание указателя базового типа
circle с; // попытка создания объекта типа circle - ОШИБКА
triangle t; // создание объектов порожденных типов
square s;
p = &t;
p->set_dim(10.0, 5.0);
p->show_area ();
p = &s;
p->set_dim(10.0, 5.0);
p->show_area();
return 0;
}

Если какой-либо класс имеет хотя бы одну виртуальную функцию, то такой класс называется абстрактным (abstract). Важной особенностью абстрактных классов является то, что не существует ни одного объекта данного класса. Вместо этого абстрактный класс служит в качестве базового для других производных классов. Причина, по которой абстрактный класс не может быть ис­пользован для объявления объекта, заключается в том, что одна или несколько его функций-членов не имеют определения. Тем не менее, даже если базовый класс является абстрактным, все равно можно объявлять указатели или ссылки на него, с помощью которых затем поддерживает­ся полиморфизм времени исполнения

























































Дата: 2019-03-05, просмотров: 167.