目录
1.C++函数重载原理
(1)C++为何可以重载?
想要知道为什么C++可以重载,首先必须知道编译器在编译C++代码时,会在内部对函数进行重命名,从而通过不同的名字调用不同的函数。那如何验证这个原因呢?看下面这段代码和它的报错信息。(本文代码运行环境均为win10系统下的vs2019)
代码一:这段代码是C++代码,将重载函数只声明,不定义。通过main函数中对重载函数的调用来得到报错信息。(只声明不定义,调用它肯定会报错的)
//代码一
#include "iostream"
using namespace std;
void Add(int a, int b);
void Add(double a, double b);
int main() {
Add(1, 2);
Add(1.1, 2.2);
}
下图是这段代码的报错信息:
观察这段代码的报错信息可以看到两个函数后的括号中是编译器在内部的重名。Add(int,int)的重命名是(?Add@@YAXHH@Z),Add(double,double)的重命名是(?Add@@YAXNN@Z)。可以推测得知,编译器用H代表int类型,N代表double类型,编译器会根据函数的参数类型来对他们进行重命名,从而实现函数重载。
(2)重载的调用原理
1.编译器在编译时,会对传递的实参类型进行推演,然后根据推演的结果选择合适的函数进行调用。如果有合适的函数,就直接调用。
2.如果没有函数的参数类型能和传递的实参类型完全匹配,编译器将会尝试对实参进行隐式类型转换。如果转换后有合适的函数,将调用此函数。
3.如果进行隐式类型转换后依然没有合适的函数能匹配则报错。
2.C语言无法重载的原因
想要知道C语言无法重载的原因,根据上文,大概也可以猜想到我们同样需要看一下C语言的编译器是如何对函数进行重命名的。我们通过代码二来验证C语言对函数的重命名方式,同样采用函数只声明不定义的办法来查看报错信息。
代码二:本代码是C语言代码。
//代码二
#include <stdio.h>
void Add(int a,int b);
int main() {
Add(2, 4);
}
下面是C语言代码的报错信息:
观察报错信息,可以看到,C语言对函数的重命名很简单,只在函数名前加一条杠,从Add变成_Add。假设C语言中可以函数重载,编译器该怎么从这样的重命名中找到合适的函数呢?毕竟C语言的重命名不会根据函数的参数,只会给函数名前加个杠。而这,就是C语言无法实现函数重载的原因。