Файл: Pobegaylo_A._C_Cplus_dlya_studenta.pdf

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

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

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

Добавлен: 13.12.2020

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

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

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

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

226 

В  любом  случае 

private

  члены  базового  класса  становятся 

private

 членами производного класса, причем доступ к этим чле-

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

private

,  а  для 

структур — в 

public

В табл. 17.1 суммированы правила действия спецификатора дос-
тупа для членов базового класса. 

Таблица 17.1.

 Спецификаторы доступа для членов базового класса 

Спецификатор 
доступа 

Доступ  
в базовом классе 

Доступ  
в производном классе 

public 

public

 

protected

 

private

 

public

 

protected

 

private

 

protected 

public

 

protected

 

private

 

protected

 

protected

 

private

 

private 

public

 

protected

 

private

 

private

 

private

 

private

 

 

17.3. Конструкторы, деструкторы  

и наследование 

Конструкторы  не  наследуются.  Если  бы  конструкторы  наследо-
вались, даже при условии их переименования, то можно было бы 
создать  объект  производного  класса  путем  вызова  конструктора 
только базового класса. А это привело бы к ошибке. Хотя конст-
рукторы и не наследуются, но при создании нового объекта про-
изводного  класса  компилятор  всегда  вызывает  конструктор  по 


background image

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

227 

умолчанию базового класса. Чтобы изменить такую инициализа-
цию  объекта  производного  класса,  нужно  в  списке  инициализа-
ции  конструктора  производного  класса  явно  вызвать  требуемый 
конструктор базового класса. 
В  листинге  17.4  приведен  явный  и  неявный  вызов  конструктора 

базового класса. 

Листинг 17.4. Явный вызов конструктора базового класса 

#include <iostream> 
using namespace std; 
struct Base 

  int n; 
  Base(const int _n = 10): n(_n) {} 
}; 
 
struct Derived: Base 

  int m; 
  Derived(const int _m = 10): m(_m) {} 
  Derived(const int _n, const int _m): Base(_n), m(_m) {} 
}; 
int main() 

  Derived c; 
  cout << c.n << ' ' << c.m << endl;  // 10 10 
 
  Derived d(5, 15); 
  cout << d.n << ' ' << d.m << endl;  // 5 15 
 
  return 0; 

При  инициализации  любого  объекта  конструкторы  вызываются 

в следующем порядке: 

1.

 

Конструкторы  базовых  классов.  Если  таких  классов  несколь-

ко,  то  их  конструкторы  вызываются  в  порядке  следования 

этих классов в списке базовых классов, а не в порядке их по-

явления в списке инициализации. 


background image

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

228 

2.

 

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

3.

 

Конструктор производного класса. 

Деструкторы не наследуются по той же причине, что и конструк-
торы. Однако при уничтожении объекта всегда вызываются дест-
рукторы  базовых  классов.  Причем  вызываются  деструкторы  в 
порядке, обратном вызову конструкторов. 
В  листинге  17.5  приведен  пример  неявного  вызова  деструктора 
базового класса. 

Листинг 17.5. Неявный вызов деструктора базового класса 

#include <iostream> 
using namespace std; 
 
class Base 

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

public: 
  ~Derived() { cout << "Derived class" << endl; } 
}; 
 
int main() 

  { 
    Derived  d; 
  } 
  // печатает: Derived class 
  // печатает: Base class 
 
  return 0; 


background image

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

229 

17.4. Наследование и присваивание 

В языке программирования C++ базовый класс совместим по ти-

пу  со  всеми  производными  от  него  классами.  Поэтому  объекты 

производных классов можно присваивать объекту базового клас-

са, но не наоборот. 
В листинге 17.6 приведен пример присваивания объекту базового 

класса объекта производного класса. 

Листинг 17.6. Присваивание объекту базового класса объекта 

производного класса 

#include <iostream> 
using namespace std; 

class Base 

  int n; 
public: 
  Base(int _n): n(_n) {} 
  int what() { return n; } 
}; 
class Derived: public Base 

  int m; 
public: 
  Derived(int _n, int _m): Base(_n), m(_m) {} 
  int what() { return m; } 
}; 

int main() 

  Base b(10); 
  Derived d(20, 20); 

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

  return 0; 


background image

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

230 

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

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

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

virtual

. В этом случае говорят, что функция производного класса 

замещает

 (

overrides

) функцию базового класса. 

В листинге 17.7 приведен пример вызова функции производного 
класса через указатель на базовый класс. 

Листинг 17.7. Вызов функции производного класса  
через указатель на базовый класс 

#include <iostream> 
using namespace std; 
 
class Base 

public: 
  virtual int what() { return 10; } 
}; 
class Derived: public Base 

public: 
  virtual int what() { return 20; } 
}; 


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