Скачиваний:
316
Добавлен:
28.03.2021
Размер:
378.53 Кб
Скачать

39. Спецификатор доступа protected, недостатки использования спецификатора protected.

Методы производного класса имеют доступ к членам базового класса, если они имеют спецификатор доступа public или protected. К членам, объявленным как private, доступа нет.

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

Таким образом, если вы пишете класс, который впоследствии будет использоваться как базовый класс при наследовании, то данные, к которым нужно будет иметь доступ, следует объявлять как protected.

Следует знать, что существуют и недостатки использования спецификатора доступа protected. Допустим, вы написали библиотеку классов и публично ее распространяете. Любой программист сможет получить доступ к членам классов, объявленным как protected, просто создавая производные классы. Это делает члены, объявленные как protected, значительно менее защищенными, чем объявленные как private. Чтобы избежать порчи данных, часто приходится разрешать доступ производным классам только к тем методам базового класса, которые объявлены как public. Однако использование спецификатора доступа protected упрощает программирование.

40. Неизменность базового класса. Конструкторы производного класса. Переопределение методов базового класса.

При наследовании базовый класс остается неизменным.

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

Для инициализации значением объекта производного класса нельзя воспользоваться конструктором базового класса с одним аргументом. Компилятор будет использовать конструктор базового класса без аргументов. Необходимо написать собственный конструктор для производного класса.

Программист может определять для определённого класса методы, имеющие такие же имена, как и у методов базового класса. Это называется переопределением методов. Переопределение методов относится к полиморфизму этапа компиляции. Решение о том, метод какого класса необходимо вызывать определяется компилятором исходя из типа объекта, для которого вызывается метод.

Пример переопределения метода базового класса:

class parent{

public:

void identify(){ cout <<”I’m a parent”;}

};

class child:public parent{

void identify(){cout <<”i’m a child”;}

};

Для вызова метода базового класса в дочернем необходимо указать имя базового класса, поставить оператор расширения области видимости и вызвать необходимый метод. Если модификатор наследования не указан, то по умолчанию для классов используется атрибут наследования private.

Конструкторы вызываются в порядке происхождения классов, а деструкторы — в обратном порядке. (При создании объекта производного класса сначала вызывается конструктор базового класса, а за ним — конструктор производного класса. При разрушении объекта производного класса сначала вызывается его "родной" конструктор, а за ним — конструктор базового класса.)

41. Использование операции разрешения при переопределении методов. Конструкторы и методы классов при наследовании. Абстрактный базовый класс Методы конструктора не наследуются, деструктор не наследуется, операция присваивания не наследуется, и дружественные функции не наследуются.

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

Human::getData();

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

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

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

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

{ public: virtual void show() = 0; //чистая виртуальная функция };

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