Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Data Structures and Algorithms in C++ 2e (На ру...docx
Скачиваний:
0
Добавлен:
01.07.2025
Размер:
2.37 Mб
Скачать

2.2. Наследование и полиморфизм

объявите, что функция печати виртуальная.

Человек класса

виртуальная недействительная печать ()

// . . .

;

Студент класса: общественный Человек

виртуальная недействительная печать ()

// . . .

;

//Человек (базовый класс)//печать (опущенные детали)

//Студент (полученный от Человека)//печать (опущенные детали)

77

Давайте рассмотрим эффект этого изменения на нашем примере множества, таким образом illus-trating полноценность динамического закрепления.

Человек* стр [100]; стр [0] = новый Человек (...); стр [1] = новый Студент (...);

стр [0]-> печать ();

стр [1]-> печать ();

// // // // //

множество 100 указателей Человека добавляет, что Человек (опущенные детали) добавляет, что Студент (опущенные детали) называет Человека:: печать () называет Студента:: печать ()

В этом случае стр [1] содержат указатель на объект Студента типа, и

власть динамического закрепления с виртуальными функциями, Студентом функции:: печать назовут. Решение, относительно которого функция звонить сделана во времени выполнения, отсюда имя динамическое закрепление.

Виртуальные печи для сжигания отходов производства

Нет такой вещи как виртуальный конструктор. Такое понятие не делает никого

смысл. Виртуальные печи для сжигания отходов производства, однако, очень важны. В нашем примере множества, так как мы храним объекты обоих Людей типов и Студента во множестве, важно, чтобы соответствующую печь для сжигания отходов производства назвали для каждого объекта. Однако, если печь для сжигания отходов производства будет невиртуальной, то только печь для сжигания отходов производства Человека назовут в каждом случае. В нашем экс-вполне достаточный, этот выбор не проблема. Но если Студенческий класс ассигновал память динамично, факт, что неправильную печь для сжигания отходов производства называют, привел бы к утечке памяти (см. Раздел 1.5.3).

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

Помните Если базовый класс определяет какие-либо виртуальные функции, он должен определить виртуальный de -

structor, даже если это пусто.

78

Глава 2. Ориентированный на объект дизайн

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

2.2.2 Полиморфизм

Буквально, «полиморфизм» означает «много форм». В контексте ориентированных на объект

дизайн, это относится к способности переменной взять различные типы. Полиморфизм, как правило, применяется в C ++ использование переменных указателя. В частности переменная p объявленный быть указателем на некоторый класс S подразумевает, что p может указать на любой объект, принадлежащий любому производному классу T S.

Теперь рассмотрите то, что происходит, если оба из этих классов определяют виртуальную членскую функцию a и позволяют нам рассмотреть, какую из этих функций называют, когда мы призываем p-> (). Так как динамическое закрепление используется, если p указывает на объект типа T, то это призывает функцию T::a. в этом случае T, как говорят, отвергает функцию от S. Альтернативно, если p укажет на объект типа S, то он призовет S::a.

Полиморфизм, такой как это полезен, потому что посетитель p-> () не должен знать, относится ли указатель p к случаю T или S, чтобы заставить функцию выполнять правильно. Переменная указателя p, который указывает на объект класса, у которого есть по крайней мере одна виртуальная функция, как говорят, полиморфная. Таким образом, p может принять много форм, в зависимости от определенного класса объекта, к которому это относится. Этот вид функциональности позволяет специализированному классу T расширять класс S, наследовать «универсальные» функции от класса S и пересматривать другие функции от класса S, чтобы составлять определенные свойства объектов класса T.

Наследование, полиморфизм и перегрузка функции поддерживают повторно используемый мягкий - изделие. Мы можем определить классы, которые наследуют универсальные членские переменные и функции и могут тогда определить новые, более определенные переменные и функции, которые имеют дело с spe-cial аспекты объектов нового класса. Например, предположите, что мы определили универсального Человека класса и затем получили трех Студентов классов, Администратора и Преподавателя. Мы могли сохранить указатели на все эти объекты в списке типа Person*. Когда мы призовем виртуальную членскую функцию, такую как печать, к любому элементу списка, это вызовет функцию, соответствующую типу отдельного элемента.

Специализация

Есть два основных способа использовать наследование, один из которых является специализацией.

В использовании специализации мы специализируем общий класс к особому производному классу. Такие производные классы, как правило, обладают, «» отношения к их базовому классу. Производные классы наследуют всех членов базового класса. Для каждой унаследованной функции, если та функция работает правильно, независимый от того, работает ли это для специализации, не необходима никакая дополнительная работа. Если, на другом