|
Программирование >> Аргументация конструирования
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!
|
© 2006 - 2024 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки. |