Перегрузка функций

редактировать
Полиморфизм
Специальный полиморфизм
Параметрический полиморфизм
Подтип

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

Например, doTask()и doTask(object o)являются перегруженными функциями. Чтобы вызвать последний, объект должен быть передан как параметр, тогда как первый не требует параметра и вызывается с пустым полем параметра. Распространенной ошибкой было бы присвоение объекту значения по умолчанию во второй функции, что привело бы к неоднозначной ошибке вызова, поскольку компилятор не знал, какой из двух методов использовать.

Другой пример - Print(object o)функция, которая выполняет разные действия в зависимости от того, печатает ли она текст или фотографии. Две разные функции могут быть перегружены как Print(text_object T); Print(image_object P). Если мы напишем перегруженные функции печати для всех объектов наша программа не будет «печать», мы не должны беспокоиться о типе объекта, и правильная функция вызова снова, вызов всегда: Print(something).

СОДЕРЖАНИЕ
  • 1 Языки, поддерживающие перегрузку
  • 2 Правила в перегрузке функций
  • 3 Перегрузка конструктора
  • 4 Осложнения
  • 5 предостережений
  • 6 См. Также
  • 7 ссылки
  • 8 Внешние ссылки
Языки, поддерживающие перегрузку

Языки, поддерживающие перегрузку функций, включают, но не обязательно ограничиваются, следующим:

Правила в перегрузке функций
  • Одно и то же имя функции используется для более чем одного определения функции.
  • Функции должны различаться как по арности, так и по типу своих параметров.

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

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

В Java перегрузка функций также известна как полиморфизм времени компиляции и статический полиморфизм.

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

Пример: перегрузка функций в C ++

#include lt;iostreamgt; int Volume(int s) { // Volume of a cube. return s * s * s; } double Volume(double r, int h) { // Volume of a cylinder. return 3.1415926 * r * r * static_castlt;doublegt;(h); } long Volume(long l, int b, int h) { // Volume of a cuboid. return l * b * h; } int main() { std::cout lt;lt; Volume(10); std::cout lt;lt; Volume(2.5, 8); std::cout lt;lt; Volume(100l, 75, 15); }

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

Перегрузка конструктора

Конструкторы, используемые для создания экземпляров объекта, также могут быть перегружены в некоторых объектно-ориентированных языках программирования. Поскольку во многих языках имя конструктора предопределено именем класса, может показаться, что конструктор может быть только один. Когда требуется несколько конструкторов, они должны быть реализованы как перегруженные функции. В C ++, по умолчанию конструкторы не имеют параметров, инстанцирование объектных пользователей с их соответствующими значениями по умолчанию. Например, конструктор по умолчанию для объекта счета в ресторане, написанный на C ++, может установить значение чаевых в 15%:

Bill() : tip(0.15), // percentage  total(0.0) { }

Недостатком этого является то, что для изменения значения созданного объекта Bill требуется два шага. Ниже показано создание и изменение значений в основной программе:

Bill cafe; cafe.tip = 0.10; cafe.total = 4.00;

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

Bill(double tip, double total) : tip(tip),  total(total) { }

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

Bill cafe(0.10, 4.00);

Это может быть полезно для повышения эффективности программы и уменьшения длины кода.

Другой причиной перегрузки конструктора может быть принудительное использование обязательных членов данных. В этом случае конструктор по умолчанию объявляется закрытым или защищенным (или, предпочтительно, удаляется, начиная с C ++ 11 ), чтобы сделать его недоступным извне. Для счета выше итоговая сумма может быть единственным параметром конструктора - поскольку у Билла нет разумного значения по умолчанию для итоговой суммы - тогда как чаевые по умолчанию равны 0,15.

Осложнения

Две проблемы взаимодействуют с перегрузкой функций и усложняют ее: маскирование имени (из-за области действия ) и неявное преобразование типа.

Если функция объявляется в одной области видимости, а затем другая функция с тем же именем объявляется во внутренней области, существует два естественных возможных поведения перегрузки: внутреннее объявление маскирует внешнее объявление (независимо от подписи) или оба внутренних объявления. и внешнее объявление оба включены в перегрузку, причем внутреннее объявление маскирует внешнее объявление, только если подпись совпадает. Первый взят из C ++: «в C ++ нет перегрузки по областям действия». В результате, чтобы получить набор перегрузки с функциями, объявленными в разных областях, необходимо явно импортировать функции из внешней области во внутреннюю область с usingключевым словом.

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

Они могут сбивать с толку: например, неточное совпадение, объявленное во внутренней области, может замаскировать точное совпадение, объявленное во внешней области.

Например, чтобы иметь производный класс с перегруженной функцией, принимающей a doubleили an int, используя функцию, принимающую intиз базового класса, в C ++ можно было бы написать:

class B { public: void F(int i); }; class D: public B { public: using B::F; void F(double d); };

Отсутствие usingрезультатов в intпараметре, переданном Fв производный класс, который преобразуется в double и соответствует функции в производном классе, а не в базовом классе; Включение usingприводит к перегрузке в производном классе и, таким образом, соответствует функции в базовом классе.

Предостережения

Если метод разработан с чрезмерным количеством перегрузок, разработчикам может быть сложно определить, какая перегрузка вызывается, просто прочитав код. Это особенно верно, если некоторые из перегруженных параметров относятся к типам, унаследованным от других возможных параметров (например, «объект»). IDE может выполнить разрешение перегрузки и отобразить (или перейти к) правильную перегрузку.

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

Смотрите также
использованная литература
внешние ссылки
Последняя правка сделана 2023-04-12 10:25:49
Содержание доступно по лицензии CC BY-SA 3.0 (если не указано иное).
Обратная связь: support@alphapedia.ru
Соглашение
О проекте