函数重载——C++

函数重载——C++,第1张

引子:

国有两个体育项目大家根本不用看,也不用担心。一个是乒乓球,一个是男足。前者是“谁也赢不了!”,后者是“谁也赢不了!”
一样的文字,不同的意思。

函数重载的定义:

函数重载:是函数的一种特殊情况,C++允许在同一作用域中声明几个功能类似的同名函数,这些同名函数的形参列表(参数个数 或 类型 或 类型顺序)不同,常用来处理实现功能类似数据类型不同的问题

//参数类型不同
int Add(int a, int b)//Add(2,5)
{
	return a + b;
}

double Add(double a, double b)//Add(2.5,5.5)
{
	return a + b;
}

//类型顺序不同
double Add(int a, double b)//Add(2,5.5)
{
	return (double)a + b;
}

int Add(double a, int b)//Add(2.5,5)
{
	return (int)a + b;
}

//参数个数不同
int Add(int a)//Add(5)
{
	return a;
}
C++支持函数重载的原理——名字修饰

运行程序的时候,会先进行预处理,编译,汇编,链接
在链接期间,会将编译期间的符号表合并,里面每个位置都有对应的名和地址,需要调用哪一个内容就根据名字找到符号表中名字对应的地址

C对于函数的函数名和地址处理到符号表中时,函数名原封不动,所以当有多个同名函数时,编译器无法区分

但是对于C++来说,在对函数的函数名和地址处理到符号表中时,会根据函数的参数来对函数名进行修饰,


以下用linux环境下来解释

  1. 采用C语言编译器编译后结果

    结论:在linux下,采用gcc编译完成后,函数名字的修饰没有发生改变

  2. 采用C++编译器编译后结果

    结论:在linux下,采用g++编译完成后,函数名字的修饰发生改变,编译器将函数参数类型信息添加到修改后的名字中

通过上面我们可以看出gcc的函数修饰后名字不变。而g++的函数修饰后变成【_Z+函数长度+函数名+类型首字母】

函数名修饰在vs下的规则:

C++编译时函数名修饰约定规则:

__stdcall调用约定:

  1. 以“?”标识函数名的开始,后跟函数名;

  2. 函数名后面以“@@YG”标识参数表的开始,后跟参数表;

  3. 参数表以代号表示:
      X–void ,
      D–char,
      E–unsigned char,
      F–short,
      H–int,
      I–unsigned int,
      J–long,
      K–unsigned long,
      M–float,
      N–double,
      _N–bool,
      …
      PA–表示指针,后面的代号表明指针类型,如果相同类型的指针连续出现,以“0”代替,一个“0”代表一次重复;

  4. 参数表的第一项为该函数的返回值类型,其后依次为参数的数据类型,指针标识在其所指数据类型前

  5. 参数表后以“@Z”标识整个名字的结束,如果该函数无参数,则以“Z”标识结束。其格式为“?functionname@@YG*****@Z”或“?functionname@@YG*XZ”,
    例如
    int Test1(char *var1,unsigned long)-----“?Test1@@YGHPAK@Z
    void Test2() -----“?Test2@@YGXXZ


__cdecl调用约定:

规则同上面的_stdcall调用约定,只是参数表的开始标识由上面的“@@YG”变为“@@YA”。


__fastcall调用约定:

规则同上面的_stdcall调用约定,只是参数表的开始标识由上面的“@@YG”变为“@@YI”。

VC++对函数的缺省声明是"__cedcl",将只能被C/C++调用

注意:

如果两个函数函数名和参数是一样的,返回值不同是不构成重载的,因为调用时编译器没办法区分
比如:

int Add(int a, int b)
{
	return a + b;
}

double Add(int a, int b)
{
	return a + b;
}

int main()
{
	Add(1,2);
	Add(2,3);
}

其实我们并没有办法区分,编译器也没有办法区分,虽然同名函数返回类型不相同,但是使用这个函数时并不会像定义函数那样标明返回类型,所以我们和编译器都无法区分这个情况

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/2991539.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-09-23
下一篇 2022-09-23

发表评论

登录后才能评论

评论列表(0条)

保存