【旧事水】overload关键词的作用
pascal吧
全部回复
仅看楼主
level 1
黄金止手 楼主
Michaël Van Canneyt 写的 ref.pdf 简直让人把关键词 overload 看得云里雾里的。
刚才实验了一下后才确定它有什么用。准确来说,是缺了 overload 关键词的重载方法会有什么影响。
FP 的模块加载顺序是
System->(ObjPas->,若模式为ObjFPC或Delphi)uses后面的第一个单元->uses后面的第二个单元->...->主程序
而分析标识符和查找重载方法的顺序是上面顺序的反转,即从主程序往前寻找,最后再找 System 。
显然类型、常量、变量不可能重载,代码中代表这些的标识符,代表的是加载链中最后一个匹配的项目。
要使用前面模块的标识符,必须冠上单元名称和点,如: system.RandSeed 、 MyUnit01.TFoo 。
而方法(函数/过程)可以重载,可以用单元名加方法名的方式使用各加载单元界面(Interface)部分声明的方法,在一定条件下可以不加单元名。
FPC 对于重载方法的处理顺序是:
若主程序或单元界面部分中,同名方法的声明至少有一个带有 overload ,那就意味着在遇到只写方法名时,允许编译器查找加载链中的前一个模块。
若该模块(单元中仅有界面部分)同名方法的声明全部都没有 overload ,则编译器查找完该模块后,就不会继续找前一个模块了。
假如找到的至少两个模块中方法的参数和返回值类型相同,那么不会出现编译错误,而是匹配加载链的最后者,正如类型、常量、变量标识符所表现。
(从加载顺序可知 System 单元的方法不需要 overload ,因为没有效果)
所以建议是:
与 System 单元中的方法(函数/过程)同名的自定义方法,最好加上 overload 关键词,否则在只写方法名的情况下会发生隐藏,即令 System 单元中的方法无法通过仅用方法名来调用。
(这个OI里用不上)你自己写的单元里,若你认为有某个方法应该把 System 单元自带的版本“覆盖”(隐藏)掉,那就不要加 overload ;反之最好加上 overload ,倘若与 System 单元自带的方法同名。
2016年09月03日 17点09分 1
level 1
黄金止手 楼主
编译器构建查找表的顺序大体是这样:
for 当前模块 in 加载模块列表 do
begin
当前方法总体:=当前模块.获取方法总体(方法名对象);
if not 当前方法总体.声明含有('overload') then
方法名对象.匹配查找表.清空;
方法名对象.匹配查找表.尾部添加(当前方法总体);
end;
编译时查找方法的顺序大体是这样:
for 当前模块 in 方法名对象.匹配查找表.逆序 do
begin
当前方法:=当前模块.获取方法(方法名对象);
if 参数匹配(当前方法.参数列表, 所需参数列表) then exit(当前方法);
end;
返回编译错误;
2016年09月03日 17点09分 2
level 9
其实,主要是为了兼容delphi,在fp模式中基本没什么效果。
毕竟,在fp中如果定义了和system库同名的函数,那么不用加overload函数也会是overload的。
2016年09月03日 23点09分 3
1