10.
35. Одиночное наследование. Преобразования указателей
Одиночное наследование
10.1. Правила наследования
Наследование является одним из трех основных механизмов ООЯП. В ре-зультате использования механизма наследования осуществляется формирование иерархических связей между описываемыми типами. Тип-наследник уточняет базовый тип.
Прототип объявления типа-наследника:
classstruct
public
имя типа : protected имя базового типа
private
описание
членов класса
Пример:
struct A {
int x,y;
};
struct B: A {
int z;
};
A a1;
B b1; b1.x = 1;
b1.y = 2;
b1.z = 3;
a1 = b1;
Объект типа B наследует свойства объекта типа A .
Таким образом, объект типа-наследника содержит внутри себя члены ба-зового типа:
При наследовании наследуются не только информационные члены, но и методы.
Не наследуются:
Конструкторы
Деструктор
Операция присваивания
59
Как уже было описано, единственный способ использования конструктора базового класса – список инициализации. Он записывается при описании кон-структора производного класса:
При создании объекта производного типа B сначала будет вызван конст-руктор базового типа A . При этом если конструктору базового типа нужны па-раметры, то его необходимо вызывать явно в списке инициализации. Затем будет вызван конструктор производного типа B .
Деструкторы вызываются в обратном порядке. При разрушении объекта производного типа сначала будет вызван деструктор этого типа, а затем дест-руктор базового типа.
Допустимо присвоение объекту базового типа объекта производного типа. При этом объекту базового типа будет присвоена та часть объекта производного типа, которая структурно совпадает с базовым типом.
10.2. Преобразования указателей.
Безопасным приведением является приведение указателя на объект ти-па-наследника к указателю на объект базового типа.
Пусть A и B – типы из предыдущего примера. Тогда
A a1; A* pa;
B b1; B* pb; pb = &b1;
pa = pb; // Указателю pa присваивается адрес объекта
// b. Т.к. указатель pa описан как указатель
// на объект типа A, то с его помощью видна
// только та часть объекта b, которая
// структурно соответствует типу A.
pa = & a1;
pb = (B*)pa; // Допустимое, но небезопасное явное
// преобразование указателя на объект
// базового типа к указателю на объект
// производного типа. Через указатель на
// объект типа B можно обращаться к
// информации, которая присутствует в
// типе В. Однако, в структуре объекта a1
// базового типа A отсутствуют
// дополнительные члены производного
// типа.
// pb ->z; // Ошибочное обращение к таким членам после
// указанного преобразования (ошибка во
// время исполнения программы).
41. Виртуальные деструкторы
Виртуальные деструкторы
Виртуальный деструктор – важная часть аппарата динамического поли-морфизма. Дело в том, что, если указатель типа базового класса указывает на объект производного класса, то при удалении объекта с использованием данного указателя в случае невиртуальности деструкторов сработает деструктор того типа, который был использован при объявлении указателя. При описании конструкто-ров и деструкторов уже было указано, что при удалении объекта во вторую оче-редь срабатывает деструктор базового типа, удаляя информационные члены ба-зового типа, унаследованные в типе-наследнике, а сначала срабатывает деструк-тор текущего объекта, удаляя дополнительные члены типа -наследника. Таким образом, деструктор базового типа применяется к объектам производного типа. Но при его локальном срабатывании не будут удалены дополнительные члены типа-наследника.
Таким образом, при создании и удалении объектов производных типов с использованием указателей необходимо описывать деструкторы как виртуаль-ные, если типы-наследники в своем составе имеют динамические структуры. При этом:
1) Виртуальный деструктор необходим и для объекта без динамических структур в случае наличия динамических структур у типа-наследника, так как деструктор, автоматически генерируемый системой по умолча-нию, является невиртуальным.
2) Несмотря на то, что имя деструктора производного класса отличается от имени деструктора базового класса, достаточно объявления деструктора виртуальным только в базовом классе.
3) Конструктор, в отличие от деструктора, нельзя описывать как вирту-альный, так как всегда срабатывает конструктор именно того типа, ко-торый используется при создании объекта, и только после создания объекта его адрес передается для присвоения указателю.
13. 47. Множественное наследование
Множественное наследование, интерфейсы
Множественное наследование возникает, когда имеется несколько базовых типов и один тип – наследник. При множественном наследовании появляется возможность моделирования более сложных отношений между типами.
class X {... };
class Y {... };
class Z: public X, public Y {... };
При описании производного класса каждый базовый класс имеет свой соб-ственный описатель типа наследования (явно указанный или неявно предпола-гаемый).
53. Специализация шаблонной функции