Перегрузка функций
 
От автора :stylin:


Что это?



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

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


#Lang "fblite"
Option
 Explicit      '' заставляем явное объявление переменных
Option ByVal         '' по умолчанию конвенция передачи по значению

'' декларации функций с аналогичной функциональностью, но которые принимают различные типы аргументов,
'' Мы «просто» создаем новые имена функций :(
Declare Function print_byte( As Byte )      '' вывод строкового byte
Declare Function print_short( As Short )    '' вывод строкового short

Dim As Byte b = 102
Dim As Short s = 10240

print_byte( b )
print_short( s )

Sleep : End 0

'' Функции определения сплющенны для краткости  ;}
Function print_byte( n As Byte ) : Print Str( n ) : Return 0: End Function
Function print_short( n As Short ) : Print Str( n ) : Return 0: End Function




Как сделать?



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

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


#Lang "fblite"
Option
 Explicit      '' заставляем явное объявление переменных
Option ByVal         '' по умолчанию конвенция передачи по значению

'' Для перегрузки функций print_numeric, мы можем\должны использовать разные типы аргументов, сохраняя при этом имя нетронутыми.
'' Мы используем ключевое слово Overload на нашей первой перегруженной функции:
Declare Function print_numeric Overload( As Byte )      '' вывод строкового byte
Declare Function print_numeric( As Short )              '' вывод строкового short
Declare Function print_numeric( As Integer )            '' вывод строкового integer
Declare Function print_numeric( As LongInt )            '' вывод строкового longint

'' объявление некоторых переменных
Dim As Byte b = 102
Dim As Short s = 10240
Dim As Integer i = 1024000000
Dim As LongInt li = 1024000000000000000

'' вводим удивительный мир перегрузки функций :)
print_numeric( b )
print_numeric( s )
print_numeric( i )
print_numeric( li )

Sleep : End 0

'' определяем наши перегруженные функции
Function print_numeric( n As Byte ) : Print Str( n ) : Return 0: End Function
Function print_numeric( n As Short ) : Print Str( n ) : Return 0: End Function
Function print_numeric( n As Integer ) : Print Str( n ) : Return 0: End Function
Function print_numeric( n As LongInt ) : Print Str( n ) : Return 0: End Function




Что это значит?



То что выделяется сразу - это легкость создания. В общем, такие методы облегчат вам жизнь и значительно сократят время на отладку.

Перегрузка функций предлагает возможность добавлять дополнительные функции (print_numeric (f as fraction)) , сохраняя ваш текущий код без изменений. Это является основой написания более качественного кода.

Заключение



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

Примечание от переводчика: я убрал некоторые строки, в которых больше "воды" , чем нужного смысла. И хоть статья была написана для freebasic более ранних версий (это видно по синтаксису Option Byval и пр.) , сама суть передана верно. Примеры пришлось чуть подправить, чтобы они компилировались и запускались.