Выбрать главу

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

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

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

class figure {

  double х, у;

 public:

  void set_dim(double i, double j =0) {

   x = i;

   У = j;

  }

  virtual void show_area() =0; // чисто виртуальная функция

};

Объявив функцию чисто виртуальной, программист создает условия, при которых производный класс просто вынужден иметь определение собственной ее реализации. Без этого компилятор выдаст сообщение об ошибке. Например, попытайтесь скомпилировать эту модифицированную версию программы вычисления площадей геометрических фигур, в которой из класса circle удалено определение функции show_area().

/* Эта программа не скомпилируется, поскольку в классе circle нет переопределения функции show_area().

*/

#include <iostream>

using namespace std;

class figure {

 protected:

  double x, y;

 public:

  void set_dim(double i, double j) {

   x = i;

   у = j;

  }

  virtual void show_area() = 0; // чисто виртуальная функция

};

class triangle : public figure {

 public:

  void show_area() {

   cout << "Треугольник с высотой ";

   cout << x << " и основанием " << у;

   cout << " имеет площадь ";

   cout << х * 0.5 * у << ".\n";

  }

};

class rectangle : public figure {

 public:

  void show_area() {

   cout << "Прямоугольник с размерами ";

   cout << x << "x" << у;

   cout << " имеет площадь ";

   cout << x * у << ".\n";

  }

};

class circle : public figure {

 // Отсутствие определения функции show_area()

 // вызовет сообщение об ошибке.

};

int main()

{

 figure *р; // создаем указатель на базовый тип

 triangle t; // создаем объекты производных классов

 rectangle r;

 circle с; // Ошибка: создание этого объекта невозможно!

 р = & t;

 p->set_dim(10.0, 5.0);

 p->show_area();

 р = & r;

 p->set_dim(10.0, 5.0);

 p->show_area();

 return 0;

}

Класс, который содержит хотя бы одну чисто виртуальную функцию, называется абстрактным.

Если класс имеет хотя бы одну чисто виртуальную функцию, его называют абстрактным. Абстрактный класс характеризуется одной важной особенностью: у такого класса не может быть объектов. Абстрактный класс можно использовать только в качестве базового, из которого будут выводиться другие классы. Причина того, что абстрактный класс нельзя использовать для создания объектов, лежит, безусловно, в том, что его одна или несколько функций не имеют определения. Но даже если базовый класс является абстрактным, его все равно можно использовать для объявления указателей и ссылок, которые необходимы для поддержки динамического полиморфизма.

Сравнение раннего связывания с поздним