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

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


sor. Однако вы можете сказать, чт eStudent СОДЕРЖИТ Advisor. Какая разница между этим отношением и наследованием?

Используем в качестве примера автомобиль. Вы можете логически определить автомобиль, как подкласс транспортных средств, а значит, он будет наследовать свойства остальных транспортных средств. С другой стороны, автомобиль содержит мотор. Если вы покупаете автомобиль, то покупаете и мотор (если, конечно, вы не покупаете

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

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

В аспекте программирования связь типа СОДЕРЖИТ достаточно очевидна. Разберем следующий пример:

class Vehicle

class Motor

Class Car : public Vehicle

public:

Motor motor;

voi (Vehicles v) ;

void raotorFn(Motors m) ;

in t mainO !

Car c;

VehicleFn(c); так можно вызвать

motorFn(c); a так - нельзя

motorFn(с.motor); нужно вот так return 0;

Вызов VehicleFn (с) допустим, поскольку с ЯВЛЯЕТСЯ Vehicle. Вызов motorFn (с) недопустим, поскольку с - не Motor, хотя он и содержит Motor. Если возникает необходимость передать функции только ту часть с, которая является мотором, это следует выразить явно: motorFn (с .motor).



Глава 22

Знакомство с виртуальными функциями-членами: настоящие ли они

/3 э/Ной главе...

Зачем нужен полиморфизм / Как работает полиморфизм

Полиморфное приготовление закуски Когда функция не является виртуальной У Виртуальные особенности

ояцчсстъо и тин аргументов функции включены в ее полное или, другими сло-А\*ами, расширенное имя. Это позволяет создавать в одной программе функции с одним и тем же именем (если различаются их полные имена):

void son>5Fn{int;

void зопчРп (char*)

void somePn (char* , double)

Во всех трех случаях функции имеют одинаковое короткое им Fn{) . Полные имена всех трех функций различаются: someFn (int) отличается от someFn (char*) и т.д. решает, какую именно функцию нужно вызвать, рассматривая полные

имена слева направо.

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

Итак, функции-члены могут быть перегружены. При этом помимо количества и типов аргументов расширенное имя функции-члена содержит еше и имя класса.

С появлением наследования возникает небольшая неувязка. Что, если функция-член базового класса имеет то же имя, что и функция-член подкласса? Попробуем разобраться с простым фрагментом кода:

class Student (

public:

. . .тс же, что и раньше . . . floc.t calcTuition () ;

clas eStudent : public Student

public;

floa uition();




in in (int argcs, char* pArgs [ ] )

Student s; GraduateStudent gs;

s.calcTuition 0; вызывает Student::calcTuition() gs.calcTuition () ; вызывает. . .

GraduateStudent:;calcTuition ()

return 0;

Как и в любой ситуации с перегрузкой, когда программист обращается

к calcTuition 0, С++ должен решить, какая именно функция calcTuitior,() вызывается. Если две функции отличаются типами аргументов, то нет никаких проблем. Даже если аргументы одинаковы, различий в именах класса достаточно, чтобы решить, какой именно вызов нужно осушествить, а значит, в этом примере нет ничего необычного. Вызов s.calcTuition(} обращается К Student::calcTuition(), поскольку S локально объявлена как Student, тогда как gs. calcTuition () обращается к GraduateStudent:;calcTuition{).

Но что, если класс объекта не может быть точно определен на этапе компиляции? Чтобы продемонстрировать подобную ситуацию, нужно просто немного изменить приведенную выше программу:

class Student

public:

то же, что и раньше float calcTuition()

return 0;

fl.CEtcalcTuitionO

voi udents x)

X.calcTuition(); к какому из calcTuition()

относится эта строка?

int main(int argcs, char* pArgs[])

Student s;

GraduateStudentgs; fn{s ) ; fn(gs);

return 0;

На этот раз вместо прямого вызова calcTuition () осуществляется вызов через промежуточную функцию fп (). Теперь все зависит от того, какой аргумент передается fn() , поскольку х может быть как Student, так и Graduate-Student. Ведь GraduateSudent ЯВЛЯЕТСЯ Student!



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

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