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

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

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

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

Языки, поддерживающие перегрузку

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

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

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

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

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

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

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

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

#включают <iostream>int Объем(int s) {  // Объем куба.  возвращаться s * s * s;}двойной Объем(двойной р, int час) {  // Объем цилиндра.  возвращаться 3.1415926 * р * р * static_cast<двойной>(час);}длинный Объем(длинный л, int б, int час) {  // Объем кубоида.  возвращаться л * б * час;}int главный() {  стандартное::cout << Объем(10);  стандартное::cout << Объем(2.5, 8);  стандартное::cout << Объем(100л, 75, 15);}

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

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

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

Счет()    : кончик(0.15), // процент      общий(0.0){ }

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

Счет кафе;кафе.кончик = 0.10;кафе.общий = 4.00;

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

Счет(двойной кончик, двойной общий)    : кончик(кончик),      общий(общий){ }

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

Счет кафе(0.10, 4.00);

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

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

Осложнения

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

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

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

Их сочетание может сбивать с толку: например, неточное совпадение, объявленное во внутренней области, может замаскировать точное совпадение, объявленное во внешней области.[2]

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

учебный класс B { общественный:  пустота F(int я);};учебный класс D : общественный B { общественный:  с помощью B::F;  пустота F(двойной d);};

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

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

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

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

Смотрите также

Рекомендации

  1. ^ «Спецификация языка Котлин». kotlinlang.org.
  2. ^ а б Страуструп, Бьярне. «Почему не работает перегрузка для производных классов?».
  3. ^ Браха, Гилад (3 сентября 2009 г.). «Системная перегрузка». Комната 101.

внешняя ссылка