在C++中,如何实现函数重载?

Ric*_*ick 17 c++ overloading function

如果没有函数重载,函数名称将作为函数代码的地址,并且在调用函数时,可以使用其名称轻松查找其地址.但是对于函数重载,程序究竟能找到正确的函数地址吗?是否存在类似于虚拟表的隐藏表,用于存储带有地址的重载函数?非常感谢!

unw*_*ind 12

编译器可以查看调用,并将其与已知的现有重载实现进行匹配,然后选择正确的实现.不需要动态表,它在编译时静态完全可行.

更新:通过显示编译器可以选择的不同命名的函数,删除了我尝试说明概念的尝试.

  • 名称修改只是为了区分标识符的名称,是否重载.名称修改的主要目的不是为了满足重载,而是为了避免命名冲突.在重载的情况下,编译器必须确定要调用哪个方法,这是主逻辑的位置.我相信OP想知道这是否是编译时/运行时的事情. (4认同)

Cra*_*rks 11

名字错误.

这一切都是在编译时完成的.C++编译器实际上修改了你在内部给它的函数名,所以函数就像

int foo(int a, float b, char c) 
Run Code Online (Sandbox Code Playgroud)

内部获得相当于的名称

func_foo_int_float_char()
Run Code Online (Sandbox Code Playgroud)

(真正的象征通常是一些gobbledygook之类的?CFoo@Foo@@QAAX_N@Z).

如您所见,根据传递的参数的确切数量和类型来装饰名称.因此,当您调用函数时,编译器很容易查看您传递的参数,使用它们修饰函数名称,并提供正确的符号.例如,

int a, b; float f; char c;
foo(a,f,c) ; // compiler looks for an internal symbol called func_foo_int_float_char
foo(a,b,c) ; // compiler looks for a symbol called func_foo_int_int_char
Run Code Online (Sandbox Code Playgroud)

同样,它完全在编译时完成.

  • 反过来说.编译器首先查看所有foos,根据标准中的所有规则选择一个匹配的foos,然后可能为链接器发出一个受损的名称. (6认同)

小智 6

如果您正在讨论同一类的重载方法,如下所示:

void function(int n);
void function(char *s);
...

objectInstance->function("Hello World")  
Run Code Online (Sandbox Code Playgroud)

这是编译时间的事情.编译器知道(或在某些情况下,做出最佳猜测)此时调用哪种方法.

我在这个问题上做了一个评论,我在这里重复一遍.

我认为,建议改名的人是误入歧途的.这并不是说编译器破坏了名称,只是在错位名称之间进行查找.它需要从可用的方法推断出正确的类型.一旦它这样做,它已经知道要调用哪种方法.然后它使用受损的名称作为最后一步.名称修改不是确定要调用哪个重载函数的先决条件.