written by :stylin:
函数重载与你没有模板一样可以进行泛型编程。在功能(或模块化)编程中,重点在于价值,而在通用编程中,重点在于
type .根据传递的参数的类型调用类似的函数。功能重载是通用编程的一个侧面,允许功能标识符与各种不同类型的功能相关联,并使其对客户端(您)都是透明的。
简单地说,函数重载涉及定义具有相同名称但不同
signatures 的函数。函数的签名是正确引用函数所需的所有信息的组合,并包括函数的参数列表和返回类型。这些是我们重新定义或重载的。我们先来一个小例子。说我们需要输出一个数字的字符串表示的函数。我们只写:
Option Explicit '' force explicit declaration of variables
Option ByVal '' default passing convention as by value
'' to declare functions with similar functionality but that accept different argument types,
'' we 'simply' create new function names :(
Declare Function print_byte( As Byte ) '' outputs a stringified byte
Declare Function print_short( As Short ) '' outputs a stringified short
Dim As Byte b = 102
Dim As Short s = 10240
print_byte( b )
print_short( s )
Sleep : End 0
'' function definitions squished for brevity - don't do this outside a space-constrained tutorial ;}
Function print_byte( n As Byte ) : Print Str( n ) : Return : End Function
Function print_short( n As Short ) : Print Str( n ) : Return : End Function
这里的问题是,我们不仅有两个不同的功能签名,还有两个不同的功能
identifiers ;我们 - 不是编译器 - 必须记住两者才能调用正确的函数。如你所想象的那样,如果您决定要支持INTEGER,SINGLE和DOUBLE,这可能会令人困惑。另外,为了完整起见,您可能希望具有接受这些功能的签名和无符号版本的功能。很明显,你将会有一些命名方案设置,使自己更容易。而且,当然你也会想支持你自己的TYPE,而且哦,等等,我们忘了指针。好的,现在您需要将您不仅需要提供的功能名称列表加倍,还可以在实际编写使用这些功能的代码时尝试并记住。因为毕竟,你有隐含的转换可用于/强制你,编译器会高兴地让你把一个DOUBLE放在你的print_integer函数中 - woops! Bug城,这里我们来吧!当然必须有更好的方法吗?
有,不要叫我雪莉。我之前提到编译器使用两个主要组件建立一个函数签名:参数列表和返回类型。我还提到,通过重载,我们可以定义具有不同签名的多个函数,并且仍然保持所有这些功能的相同的功能名称。你可能会认为这是我们走出我们的困境,卷曲的名字空间和所有的方式。嗯,你是对的 - 检查一下:
Option Explicit '' force explicit declaration of variables
Option ByVal '' default passing convention as by value
'' to overload function print_numeric that we can redefine to accept different argument
'' types while keeping the name intact, we use the OVERLOAD keyword on our intial function:
Declare Function print_numeric Overload( As Byte ) '' outputs a stringified byte
Declare Function print_numeric( As Short ) '' outputs a stringified short
Declare Function print_numeric( As Integer ) '' outputs a stringified integer
Declare Function print_numeric( As LongInt ) '' outputs a stringified longint
'' define some variables
Dim As Byte b = 102
Dim As Short s = 10240
Dim As Integer i = 1024000000
Dim As LongInt li = 1024000000000000000
'' enter the wonderful world of function overloading :)
print_numeric( b )
print_numeric( s )
print_numeric( i )
print_numeric( li )
Sleep : End 0
'' define our function overloads
Function print_numeric( n As Byte ) : Print Str( n ) : Return : End Function
Function print_numeric( n As Short ) : Print Str( n ) : Return : End Function
Function print_numeric( n As Integer ) : Print Str( n ) : Return : End Function
Function print_numeric( n As LongInt ) : Print Str( n ) : Return : End Function
应该立即脱颖而出的一件事是做得如此难以置信。考虑到自由,灵活性和
type-safety 如果提供给你,但是然后又是最高级别的结构就是这样,这可能看起来很奇怪。简而言之,使用这样的方法不仅可以使您的生活变得更容易,而且您将花费更少的时间来调试,无论您编写什么样的代码,这都是一件好事。
这意味着
flexibility .功能重载提供了添加更多功能的能力(print_numeric(f as fraction)),同时仍保持当前的代码不变。您的代码不会中断,因为您希望支持打印手帕,装甲或其他任何数字表示。你现在可能会认为上面的代码不是那么简单,而且看起来真的很简单 - 因为它是真正的编写更好的代码的基础。你会对的
这意味着
maintainability :所以你有你的80个函数print_some_long_name_you_need_to_look_up_everytime_you_want_to_use_it被编写和调试。一切都在你的小恶魔,自我厌恶的世界中很棒。当需要改变的时候会发生什么?即使只有其中一项功能需要改变,BAM!维护噩梦您将不得不搜索整个代码库
completely ,确保您没有错过这里或那里的功能;难过的方式来度过一个星期六晚上,我的朋友。
这意味着
safety :您可能会注意到,我在这些示例中使用了两个选项:
选项显式和
选项ByVal.我的安全性很大,而且编译器为我看的时候更大了。我使用这些,因为它更安全,我会采取所有的安全,我可以得到。功能重载也为您提供安全 - 防止恶意(读取:意外)隐式转换。考虑我们是否真的从这些函数中返回一个依赖于我们传递给它的参数的值。如上所述,如果没有我们的知识允许双倍被截断,那么就会出现许多excedrin药丸,试图使调试头痛消失。这一切都是关于类型安全的,这导致许多人嘲笑C
pp .
我希望你至少学到了功能重载的基础知识(因为这是我所有的)。我希望你开始考虑我所提出的主题,如果你以前没有。下一次我将讨论使用不同数量的参数,不同的返回类型以及两者的快乐和陷阱来重载函数。敬请关注。