Архитектура Аудит Военная наука Иностранные языки Медицина Металлургия Метрология Образование Политология Производство Психология Стандартизация Технологии |
При открытом наследовании
1. Закрытые элементы базового класса доступны в базовом классе элементам и друзьям базового класса 2. Защищенные элементы базового класса доступны элементам и друзьям как базового, так и производного класса 3. Открытые элемента базового класса доступны всем функциям, доступ через имя объекта 4. Элементы производного класса ссылаются на элементы базового класса просто по имени
При закрытом наследовании: 1. Некоторые функции класса можно сделать доступными Class B {… public: Void f(); …. }
Class A : private B {… Public: B::void f(); … }
Пример простого наследования: #include <iostream.h> #include <iomanip.h> Class point // базовый класс - точка {friend ostream& operator << (ostream&, const point&); // первый параметр функции – не является объектом данного класса и поэтому эта функция не может быть функцией-элементом класса, но так как она должна иметь доступ к закрытой части класса, где находятся координаты точки, она объявляется дружественно. Public: Point (float=0, float=0); // конструктор с умолчанием Void setpoint (float, float); // функция установки координат Float getx () {return x;}; Float gety () {return y;}; Protected: Float x, y; };
Примечание: в одиночном классе спецификаторы private и protected равноценны, т.е. доступ к элементам в этих разделах возможен только через функции-элементы открытой части, а при наследовании большая разница – элементы в разделе private остаются в производном классе недоступными, а в protected – доступны. Point :: point (float a, float b) {setpoint (a,b); }
Void point :: setpoint (float a, float b) {x=a; y=b; }
// вывод данных в форме [x,y], Ostream & operator << (ostream & output, const point & p) {output << ‘[‘ << p.x << ‘,’ << p.y << ‘]’ ; Return output; }
Примечание: возвращение ссылки на объект позволяет осуществлять сцепленные выводы объекта. P1, p2, p3 …. Cout << p1 << p2 << p3 Class circle :: public point // производный класс - окружность {friend ostream & operator << (ostream &, const circle &); Public: Circle (float r=0.0, float x=0.0, float y=0.0); Void setradius (float); // установка радиуса Float getradius () const; // возвращение радиуса Protected; Float radius; }
Circle :: circle (float r, float a, float b) : point (a, b) // вызов конструктора базового класса в списке инициализацией (явно) {radius=r; }
// вывод данных объекта circle в форме: Центр =[x,y]; Радиус = #.## Ostream & operator << (ostream & output, const circle & c) {output << “Центр =[ ” << c.x << ‘, ’ << с.y << “]; Радиус = ” << setiosflags (ios::showpoint) << setprecision (2) << c.radius; Return output; }
Void main () {point * pptr, p (3.5, 5.3); Circle *cptr, с (2.7, 1.2, 8.9); Cout << “p:” << p << endl; // p:[3.5, 5.3] Cout << “c:” << с << endl; // Центр =[1.2, 8.9]; Радиус=2.70 // рассмотрение объекта с как объект р Pptr=&c; Cout << endl << “с через *pptr : ” << *pptr <<endl; // с через *pptr: [1.2, 8.9], следовательно производный класс является и базовым // рассмотрение объекта с после приведения типа pptr Cptr =(circle* ) pptr; // приведение базового типа к производному типу Cout << endl << “c через *cptr: “ << *cptr << endl; // с через *cptr: Центр = [1.2, 8.9]; Радиус = 2.70; Для того, чтобы через указатель на базовый класс pptr увидеть объект производного класса с необходимо: 1. Присвоить указателю pptr адрес объекта с 2. А затем указатель pptr привести к типу производного класса
Pptr=&p; Cptr = (circle * )pptr; Cout << endl << “p через *cptr : ” << *cptr << endl; // p через *cptr : Центр = [3.5, 5.3]; Радиус = 4.02e-38 Примечание: если указателю pptr присвоить адрес объекта р, а затем привести к типу производного класса, то через этот указатель будет виден только базовый класс. }
Примечание: 1. Производный класс наследует функции-элементы setpoint, getx, gety и данные-элементы x, y из базового класса 2. В производном классе введены данные-элемент radius, определен собственный конструктор, добавлены функции-элементы setradius и getradius 3. В базовом классе используется спецификатор protected, чтобы x и y были доступны в производном классе ● Правила наследования функций-элементов Наследуется все, кроме: 1. Конструкторов 2. Операций присваивания 3. Деструкторов
1. Конструкторы не наследуются, поэтому производный класс должен иметь свой собственный конструктор. Порядок вызова конструктора производного класса следующий: ● Если в производном классе конструктор не имеет явного вызова конструктора базового класса, то автоматически вызывается конструктор базового класса с умолчанием, т.е. тот, который можно вызвать без параметров ● Если конструктор базового класса требует указания параметров (наш случай), он вызывается в конструкторе производного класса в списке инициализации ● Если базовых классов несколько (множественное наследование), то их конструкторы вызываются в порядке объявления ● В иерархии, состоящей из нескольких уровней, конструкторы базовых классов вызываются, начиная с самого верхнего уровня, после этого вызываются конструкторы классов для создания объектов, которые используются в производном классе, как элементы, и в последнюю очередь вызываются конструкторы производного класса
2. Вызов деструкторов: ● Если в производном классе нет деструктора, то он формируется по умолчанию, и вызывает деструкторы всех базовых классов ● В отличие от конструкторов, деструкторы не требуют явного вызова деструкторов базового класса, т.к. это делается автоматически 3. В иерархии их нескольких классов деструкторы всегда вызываются в последовательности, обратной вызовам конструкторов, т.е. вначале деструктор производного класса, потом стоящего над ним и т.д. до начала иерархии.
|
Последнее изменение этой страницы: 2019-05-08; Просмотров: 164; Нарушение авторского права страницы