Файл: Pobegaylo_A._C_Cplus_dlya_studenta.pdf

ВУЗ: Не указан

Категория: Не указан

Дисциплина: Не указана

Добавлен: 13.12.2020

Просмотров: 4315

Скачиваний: 28

ВНИМАНИЕ! Если данный файл нарушает Ваши авторские права, то обязательно сообщите нам.
background image

Часть II. Язык программирования С++ 

236 

class Derived: public Base 

public: 
  virtual ~Derived() { cout << "~Derived" << endl; } 
}; 

int main() 

  Base* b = new Derived; 
  delete b;  // ~Derived ~Base 
 
  return 0; 

17.9. Абстрактные классы 

Виртуальная функция называется 

чистой

 (pure), если она опреде-

лена только как спецификатор интерфейса, т. е. 

не имеет реали-

зации

. Чисто виртуальные функции имеют следующий прототип: 

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

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

абстрактным 

(abstract)

  классом

.  Такой  класс 

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

 

абстрактный  класс  не  может  использоваться  в  качестве  аргу-
мента или типа возвращаемого функцией значения; 

 

абстрактный класс нельзя использовать в явном  преобразова-
нии типов. 

Можно  определить  указатель  или  ссылку  на  абстрактный 
класс — это позволит использовать абстрактные классы для опи-


background image

Глава 17. Наследование классов 

237 

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

Листинг 17.12. Ссылка на абстрактный класс 

#include <iostream> 
using namespace std; 

class Abstract 

public: 
  virtual int what() = 0; 
  virtual ~Abstract() {} 
}; 
class Concrete: public Abstract 

public: 
  virtual int what() { return 10; } 
  virtual ~Concrete() {} 
}; 
int foo(Abstract& a) 

  return a.what(); 

int main() 


background image

Часть II. Язык программирования С++ 

238 

  Concrete c; 
  cout << foo(c) << endl;  // 10 

  return 0; 

17.10. Множественное наследование 

В языке программирования C++ разрешается наследовать произ-
водный  класс  от  нескольких  базовых  классов.  Такое  наследова-
ние называется 

множественным

 (multiple). В иерархии с множе-

ственным  наследованием  производный  класс  может  косвенно 
наследовать несколько экземпляров базового класса. В этом слу-
чае  для  доступа  к  повторяющимся  членам  базового  класса  ис-
пользуется оператор разрешения области видимости 

::

  с  имена-

ми базовых классов в качестве квалификаторов. 
В листинге 17.13 приведен пример множественного наследования 
классов. 

Листинг 17.13. Множественное наследование классов 

#include <iostream> 
using namespace std; 
 
struct Base 

  int n; 
  int what() { return n; } 
}; 
struct Derived_1: Base {}; 
struct Derived_2: Base {}; 
struct Derived: Derived_1, Derived_2 {}; 
 
int main() 

  Derived d; 
 
  d.Derived_1::n = 10; 
  d.Derived_2::n = 20; 


background image

Глава 17. Наследование классов 

239 

  cout << d.Derived_1::what() << endl;  // печатает: 10 
  cout << d.Derived_2::what() << endl;  // печатает: 20 
 
  return 0; 

17.11. Виртуальное наследование 

Для того чтобы исключить передачу нескольких экземпляров ба-
зового  класса  по  иерархии  при  множественном  наследовании, 
непосредственные  потомки  этого  базового  класса  должны  объ- 
явить  его  виртуальным  при  помощи  ключевого  слова 

virtual

  

в  списке  базовых  классов.  Такое  наследование  базового  класса 
называется 

виртуальным

,  а  сам  базовый  класс  называется 

вир-

туальным базовым классом

В  листинге  17.14  приведен  пример  наследования  членов  вирту-
ального базового класса. 

Листинг 17.14. Наследование членов виртуального базового  
класса 

#include <iostream> 
using namespace std; 
 
struct Base 

  int n; 
  int what() { return n; } 
}; 
struct Derived_1: virtual Base {}; 
struct Derived_2: virtual Base {}; 
struct Derived: Derived_1, Derived_2 {}; 
 
int main() 

  Derived d; 
 
  d.n = 10; 
  cout << d.what() << endl;  // печатает: 10 


background image

Часть II. Язык программирования С++ 

240 

  return 0; 

При виртуальном наследовании необходимо, чтобы конструктор 
виртуального базового класса вызывался только один раз. Поэто-
му  при  создании  объекта  производного  класса  сначала  вызыва-
ются  конструкторы  всех  базовых  виртуальных  классов,  а  затем 
конструкторы остальных базовых классов в порядке их следова-
ния в иерархии. 


Смотрите также файлы