Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Лекции_С++_последная.doc
Скачиваний:
40
Добавлен:
07.05.2019
Размер:
876.54 Кб
Скачать

9.1. Простое открытое наследование

Простым (или одиночным) называется наследование, при котором производный класс имеет только одного родителя. Формально наследование одного класса от другого задается следующей конструкций:

сlass имя_класса_потомка: [модификатор_доступа]   имя_базового_класса

{ тело_класса }

Модификатор доступа определяет доступность элементов базового класса в классе-наследнике. Квадратные скобки не являются элементом синтаксиса, а показывают, что модификатор может отсутствовать. Этот модификатор называется модификатором наследования.

При разработке отдельных классов используются два модификатора доступа к элементам класса: public (общий) и private (личный). При наследовании применяется еще один: protected (защищенный). Защищенные элементы класса доступны только прямым наследникам и никому другому.

Возможны четыре варианта наследования: класс от класса; класс от структуры; структура от структуры; структура от класса.

Доступность элементов базового класса из классов-наследников изменяется в зависимости от модификаторов доступа в базовом классе и модификатора наследования. Каким бы ни был модификатор наследования, приватные элементы базового класса недоступны в его потомках.

Если модификатор наследования – public, наследование называется открытым. Модификатор protected определяет защищенное наследование, а слово private означает закрытое наследование.

9.1.1 Конструкторы и деструкторы при наследовании

Конструкторы не наследуются – они создаются в производном классе (если не определены программистом явно). Система поступает с конструкторами следующим образом:

- если в базовом классе нет конструкторов или есть конструктор без аргументов (или аргументы присваиваются по умолчанию), то в производном классе конструктор можно не писать – будут созданы конструктор копирования и конструктор без аргументов;

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

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

// Базовый класс - с конструкторами по умолчанию

class Money

{ public: // конструктор инициализации и без аргументов

Money (const double &r = 0.0) { Surma = d; }

private:

double Summa;

};

// класс-наследник без конструкторов

class Backs: public Money { };

class Basis

{ int a,b;

public: // только явные конструкторы с аргументами

Basis(int x, int у) { а=х; b=у; }

};

class Inherit: public Basis

{ int sum:

public:

Inherit(int x, int y, int s)

:Basis(x,y) // явный вызов конструктора

{ sum=s ; }

};

В классе Money определен конструктор инициализации, который играет роль и конструктора без аргументов, так как аргумент задан по умолчанию. В классе-наследнике Backs конструкторы можно не писать. Во втором случае в классе Basis определен только конструктор инициализации (конструктор копирования создается автоматически, а конструктор без аргументов – нет). В классе-наследнике Inherit конструктор базового класса явно вызывается в списке инициализации.

Деструктор класса, как и конструкторы, не наследуется, а создается. С деструкторами система поступает следующим образом:

- при отсутствии деструктора в производном классе система создает деструктор по умолчанию;

- деструктор базового класса вызывается в деструкторе производного класса автоматически независимо от того, определен он явно или создан системой;

- деструкторы вызываются (для уничтожения объектов) в порядке, обратном вызову конструкторов.

Создание и уничтожение объектов выполняется по принципу LIFO: последним создан – первым уничтожен.