Архитектура Аудит Военная наука Иностранные языки Медицина Металлургия Метрология
Образование Политология Производство Психология Стандартизация Технологии


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



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; Нарушение авторского права страницы


lektsia.com 2007 - 2024 год. Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав! (0.016 с.)
Главная | Случайная страница | Обратная связь