在C++中可以为两个或两个以上的函数提供相同的函数名称,只要参数类型不同,或参数类型相同而参数的个数不同, 称为函数重载。
示例:
// my_max + 参数表
int my_max(int a,int b)
{
return a > b ? a : b;
}
char my_max(char a,char b)
{
return a > b ? a : b;
}
double my_max(double a,double b)
{
return a > b ? a : b;
}
//每个同名函数的参数表是惟一,
int main()
{
int ix = my_max(12,23);
double dx = my_max(12.23,34.45);
char chx = my_max('a','b');
return 0;
}
示例:
int my_max(int a,int b)
{
return a > b ? a : b;
}
unsigned int my_max(int a,int b) // error;
{
return a > b ? a : b;
}
int main()
{
int ix = my_max(12,23);
unsigned int = my_max(12,23); // error;
reutrn 0;
}
示例:
// 声明同一个函数
int my_add(int a,int b);
int my_add(int x,int y);
示例:
void Print(int *br,int n);
void Print(int *br,int len = 10);
示例:
typedef unsigned int u_int;
int Print(u_int a)
int Print(unsigned int b);
示例:
void fun(int a){ }
void fun(const int a) { }
示例:
void fun(int *p) {}
void fun(const int *p) {}
void fun(int &a) {}
void fun(const int &a) {}
void fun(int a){}
void fun(int a,int b){}
void fun(int a ,int b = 10);
“C”或者“C++”函数在内部(编译和链接)通过修饰名识别。修饰名是编译器在编译函数定义或者原型时生成的字符串。
修饰名由函数名、类名、调用约定、返回类型、参数等共同决定。
_stdcall 是Pascal程序的缺省调用方式,通常用于Win32 Api中,函数采用从右到左的压栈方式,自己在退出时清空堆栈。
C调用约定(即用 _cdecl 关键字说明)按从右至左的顺序压参数入栈,由调用者把参数弹出栈。对于传送参数的内存栈是由调用者来维护的(正因为如此,实现可变参数的函数只能使用该调用约定)。
thiscall 仅仅应用于“ C++ ”类的成员函数。 this 指针存放于ECX 寄存器,参数从右到左压。thiscall 不是关键词,因此不能被程序员指定。
在C/C++中,一个程序要运行起来,需要经历以下几个阶段:预编译(预处理)、编译、汇编、链接。Name Mangling是一种在编译过程中,将函数名、变量名的名字重新命名的机制。
(1)C语言的名字修饰规则非常简单,_cdecl是C/C++的缺省调用方式, 调用约定函数名字前面添加了下划线前缀。
格式:_functionname
(2)_stdcall调用约定在输出函数名前加上一个下划线前缀,后面加上一个“@”符号和其参数的字节数。
格式:_functionname@number
(3)_fastcall 调用约定在输出函数名前加上一个“ @ ”符号,函数名后面也是一个“ @ ”符号和其参数的字节数
格式:@functionname@number
_cdecl 调用约定:
1、以“?”标识函数名的开始,后跟函数名;
2、函数名后面以“@@YA”标识参数表的开始,后跟参数表;
3、参数表以代号表示:
4、参数表的第一项为该函数的返回值类型,其后依次为参数的数据类型,指针标识在其所指数据类型前;
5、参数表后以“@Z”标识整个名字的结束,如果该函数无参数,则以“ Z ”标识结束
//(?my_add_int@@YGHHH@Z)
int __stdcall my_add_int(int a, int b)
{
return a + b;
}
int main()
{
my_add_int(12, 23);
return 0;
}
//(?my_max@@YAHHH@Z)
int my_max(int a, int b);
//(?my_max@@YADDD@Z)
char my_max(char a, char b);
//(?my_max@@YANNN@Z)
double my_max(double a, double b);
int main()
{
my_max(12, 23);
my_max('a', 'b');
my_max(12.23, 34.45);
return 0;
}
关键字 :
extern “C” : 函数名以C的方式修饰约定规则;
extern “C++” : 函数名以C++的方式修饰约定规则;
为了代码重用,代码就必须是通用的;通用的代码就必须不受数据类型的限制。
函数模板可以用来创建一个通用功能的函数,以支持多种不同形参,简化重载函数的设计。
函数模板定义如下:
template<模板参数表>
返回类型 函数名(形式参数表)
{
...;//函数体
}
<模板参数表>(template parameter list)尖括号中不能为空,参数可以有多个,用逗号分开。模板参数主要是模板类型参数。
模板类型参数 (template type parameter) 代表一种类型 , 由关键字 class 或 typename ( 建议用typename) 后加一个标识符构成,在这里两个关键字的意义相同,它们表示后面的参数名代表一个潜在的内置或用户设计的类型。
示例:
template<class T>
T my_max(T a, T b)
{
return a > b? a:b;
}
int main()
{
my_max(12, 23);
my_max('a', 'b');
my_max(12.23, 34.45);
return 0;
}