Переопределение и перегрузка функции в C ++ и Delphi
Spacessoft 【темный ночной песок】
В объектно-ориентированном программировании, когда подкласс продолжает функции из базового класса, подклассу может потребоваться иметь дело с некоторыми функциями иначе, чем базовый класс, например:
Класс Чуман
{
публика:
void saymyname () // Распечатайте имя объекта
{
cout << Привет, я человек << endl;
}
};
Тогда очевидно, что если у его подкласса есть функция Saymyname с тем же именем, тем же параметром и возвращаемым значением (одно предложение, та же функция), какую функцию он вызовет? Например, сейчас есть класс Cmark
Класс Cmark: Public Chuman
{
публика:
void saymyname ()
{
cout << Привет, я Марк << endl;
}
};
Тогда мы должны спросить, следующий сегмент программы:
Chuman *ph = new cmark;
if (ph)
ph-> saymyname ();
еще
Cout << ошибка бросается!
Удалить pH;
ph = null;
Привет, я отмечен, мы хотим распечатать?
нет. Это выводит привет, я человек. Это ужасно, и когда мы указываем на человека и просим его сказать его имя, он говорит нам, что он «человек», а не произносит свое имя. Причина этой проблемы заключается в том, что указывая на публичный полученный класс с помощью указателя базового класса, вы можете получить доступ к функциям элементов полученного класса, которые продолжаются из базового класса. Но если в полученном классе есть функции с тем же именем, результат все еще доступа к функции того же имени базового класса, а не функции самого полученного класса. Фактически, мы хотим определить, какие из этих функций с тем же именем следует вызывать реальным типом объекта, то есть такое разрешение динамично. Или мы можем сказать, что когда объект является подтипом, его реализация с тем же именем в подклассе переопределяет реализацию базового класса.
Давайте начнем с обработки этой проблемы C ++.
Это типичный пример полиморфизма в C ++. Чтобы быть конкретным, он должен использовать виртуальные ключевые слова, чтобы описать функцию как виртуальную функцию.
Класс Чуман
{
публика:
Virtual void SaymyName () // Распечатайте имя объекта
{
cout << Привет, я человек << endl;
}
};
Таким образом, другие коды остаются одинаковыми, но наш Cmark уже знает, как сказать его название. Неважно, добавила ли функция saymyname () Cmark виртуальное ключевое слово, поскольку в соответствии с положениями синтаксиса C ++, поскольку оно переопределяет функцию чумана одного и того же имени, он становится виртуальным. Что касается того, почему виртуальное ключевое слово имеет такой волшебный эффект? C ++ FAQ Lite объясняет это следующим образом: В C ++ «Виртуальные функции членов динамически определяются (во время выполнения). То есть функции членов (во время выполнения) выбираются динамически, а выбор основан на типе объекта., А не. Тип указателя/ссылки на этот объект ». Таким образом, наш PH обнаруживает, что на самом деле он указывает на объект типа C, а не на Chuman, объявленный своим собственным типом, поэтому он умно называет Cmark Saymyname.
Delphi использует переопределение ключевых слов, чтобы проиллюстрировать переопределение функции. Переписанная функция должна быть виртуальной или динамической, то есть функция должна содержать один из этих двух показателей при объявлении, например:
Процедура рисовать;
Когда вам нужно переопределить, вам просто нужно восстановить его с помощью индикатора переопределения в подклассе.
Процедура рисовать;
Синтаксически, объявления как виртуальные и динамические эквивалентны. Разница в том, что первая оптимизирует скорость в реализации, в то время как последний оптимизирует размер кода.
Что, если и базовый класс, и подкласс содержат одно и то же имя и параметр функции, а индикатор переопределения не добавляется в подкласс? Это также синтаксически правильно. Это означает, что реализация функции функции подкласса скрывает реализацию базового класса, хотя оба существуют в полученном классе. Тогда давайте вернемся к ситуации, показанной в первом примере в начале этой статьи: когда мы указываем на человека и попросим его произнести свое имя, он говорит нам, что он «человек», вместо того, чтобы сказать свое имя.
Стоит отметить, что в отличие от функции перегрузки и функции перегрузки, которую мы часто называем перегрузкой в C ++, в Delphi только перегрузка - это то, что мы обычно называем перегрузкой. Конечно, когда функция сброшена перегрузка, такая же, как параметры функции базового класса, реализация базового класса скрыта, как и упомянутая выше. Переопределение означает, что перезаписанная функция невидимой и действительно перезаписывается, и исходная реализация исчезнет. По этой причине многие статьи и даже некоторые книги ошибочно перевели переопределение в перегрузку, что, я думаю, не подходит.