Программирование >>  Аргументация конструирования 

1 ... 69 70 71 [ 72 ] 73 74 75 ... 108


: В C + + мы говорим, что клас dent наследует класс Person. Кроме того, мы [ говорим, что Person является базовым классом ддя класса student. Наконец, мы i говорим, что student ЯВЛЯЕТСЯ Person (использование прописных букв - общепринятый метод отражения уникального типа связи; не я это придумал). Эта

терминология используется в C++ и других объектно-ориентированных языках

программирования.

; Заметьте, что хотя student и ЯВЛЯЕТСЯ Person, обратное не верно. Person не

ЯВЛЯЕТСЯ Student (такое выражение следует трактовать в общем смысле, поскольку конкретный человек, конечно же, может оказаться студентом). Существует много людей, которые явжются членами класса Person и не являются членами класса student.

Кроме того, класс student имеет средний балл, a Person его не имеет.

Свойство наследования транзитивно. Например, если я определю новый класс : GraduateStudent как подкласс класса student, то он тоже будет наследником :

Person. Это значит, что будет выполняться следующее: если GraduateStudent ЯВЛЯЕТСЯ Student и Student ЯВЛЯЕТСЯ Person, то GraduateStudent ЯВЛЯЕТСЯ Person.

fioK fuzcAeqifetflcA класс

Здесь приведен пример уже рассмотренного класса GraduateStudent, который

дополнен несколькими членами.

ttinclude <string.h>

class Acvisor

public:

Stud.;nt (char *pName = ГО Пап: )


5trncpy(name, pName, sizeof(name)); leverage = 0.0;

feddCourse(int= Hours, float grade)

average = (semest

semesterHours

average =


s average

semesterHours;

grade) ;

int hours( Д float gpa{


.urs ;

semesterHours; } 1 average;)



public:

in fier( > { return qualifierGrade; };

protected:

Advisor advisor; int qualifierGrade;

in in ( )

Student lluCLo Lee Undergrad ); GraduateStudent gs; llu.addCourse(3,2.5); gs.addCourse(3,3.0);

return 0;

В этом примере класс Student содержит тс же члены, что и ранее. Объект iu - просто один из объектов Student. Класс GraduateStudent несколько отличается по структуре от класса Student; двоеточие и следующее за ним public dent объявляет класс GraduateStudent наследником Student.

Ключевое слово public наводит на мысль о том, что может существовать и защищенное наследование, однако его обсуждение вгходит за рамки нашей книги (вы еше

не забыли этот термин?).

Объект gs как член подкласса может делать то же, что и объект Он

содержит данные-члены паше, senesterHours, average и функцию-член addCourse (). Кроме того, GraduateStuder.t содержит также члены qualif.ier(), advisor и qualifierGrade- Таким образом, gs в прямом смысле этого слова ЯВЛЯЕТСЯ классом Student плюс кое-что еше.

Разберем приведенный ниже сценарий.

void fn(Students s)

все, что угодно.. .

{{tПEdIl( )

Graidltllfet gs; fn(gs) ;

rebjmo;

Обратите внимание, что функция f п () нринимает в качестве аргумента ссылку на объект класса student. Однако в main() мы передаем ей объект класса GraduateStudent. Функция спокойно принимает этот аргумент именно потому, что (а ну-ка еше раз, все вместе!) GraduateStudent ЯВЛЯЕТСЯ Student .

Это же условие позволяет вызывать функцию-член класса Student из объекта

класса GraduateStudent, как это делается в приведенном ниже примере.

int main( )

GraduateStudent

вызываем функцию Student: :addCourse () gs.addCourse (3, 2.5) ; ) return 0;



fioHOfifUfUftaaHue подкласса

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

Перед тем как управление получает код, стоящий за открывающей фигурной скобкой класса GraduateStudent, оно передается конструктору по умолчанию класса Student (поскольку другой конструктор не бьш указан). Если бы класс student бьш наследником другого класса, например Person, то конструктор этого класса вызывался бы перед передачей управления конструктору student. Подобно небоскребу, объект строится, начиная с фундаментального уровня в соответствии со структурой наследования классов и вызывая конструкторы всех классов, составляющих данный.

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

class GraduateStudent : public Student {

public:

GraduateSrudenr(char pMame,

Advisors adv) : Student(pName), advisor(adv)

qualifierGrade = 0;

все ос iioe такое же, как и раньше } ;

void fn(Advisors advisor)

GraduateStudent gsCYen Кг Doodle , advisor);

.все остальное, что должна лать эта функция...

В ЭТОМ примере конструктор класса GraduateStudent вызывает конструктор Student, передавая ему аргумент pName. Базовый класс конструируется до любых объектов-членов, а значит, конструктор класса Student вызывается перед конструктором Advisor. И только после конструктора Advisor (который вызывается для члена advisor) начинает работу конструктор GraduateStudent.

Следуя правилу о том, что деструкторы вызываются в порядке, обратном вызову конструкторов, первым вызывается уктор GraduateStudent. После того как он свою работу, управление передается деструктору класса Advisor, а затем деструктору Student. Если бы student б]л наследником класса Person, его деструктор получил бы управление после деструктора student.

И это логично. Блок памяти сначата преобразуется в объект student, а уже затем конструктор для GraduateStudent превращает этого студента в аспиранта. Деструктор же просто выполняет этот процесс в обратном направлении.

OifUwiueHue СОМШОМ

Обратите внимание, что класс GraduateStudent включает в себя члены классов Student и Advisor, однако он включает их по-разному. Определяя данные-члены класса Advisor, вы знаете, что класс Student содержит внутри все данные-члены класса Advisor, но вы не можете сказать, что GraduateStudent ЯВЛЯЕТСЯ Advi-



1 ... 69 70 71 [ 72 ] 73 74 75 ... 108

© 2006 - 2024 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки.
Яндекс.Метрика