C++深度解析 函数重载分析--函数指针,函数重载,C++和C相互调用(8)
函数指针
typedef 返回类型(*新类型)(参数表)
typedef char (*PTRFUN)(int);
PTRFUN pFun;
char glFun(int a){ return;}
void main()
{
pFun = glFun;
(*pFun)(2);
}
typedef的功能是定义新的类型。第一句就是定义了一种PTRFUN的类型,并定义这种类型为指向某种函数的指针,这种函数以一个int为参数并返回char类型。后面就可以像使用int,char一样使用PTRFUN了。 第二行的代码便使用这个新类型定义了变量pFun。
函数重载 VS 函数指针
函数重载遇上函数指针时:
将重载函数名赋值给函数指针时
1、根据重载规则挑选与函数指针参数列表一致的候选者
2、严格匹配候选者的函数类型与函数指针的函数类型
示例程序:(函数重载 VS 函数指针)
#include <stdio.h>
#include <string.h>
int func(int x)
{
return x;
}
int func(int a, int b)
{
return a + b;
}
int func(char* s)
{
return strlen(s);
}
//函数指针类型PFUNC
typedef int(*PFUNC)(int a);
int main(int argc, char* argv[])
{
int c = 0;
//函数指针p
PFUNC p = func;
//根据函数指针p,所指向参数列表进行选择:(int a)
//严格匹配函数类型:int
c = p(1);
printf("c = %d\n", c);
return 0;
}
结果如下:
从上述例子,注意:
函数重载必然发生在同一个作用域中。
编译器需要用参数列表或函数类型进行函数选择。
无法直接通过函数名得到重载函数的入口地址(参考上一章节的最后一个例子!!!!)
C++和C相互调用
C++编译器要兼容C语言的编译方式。
C++编译器会优先使用C++编译的方式
extern关键字能强制让C++编译器进行C方式的编译
//告诉C++编译器,下面的代码是以C语言的方式编译
extern "C"
{
//do C-style compilation here
}
示例程序:(新建立一个文件夹)
add.h
int add(int a, int b);
add.c
#include "add.h"
int add(int a, int b)
{
return a + b;
}
main.cpp(调用C函数)
#include <stdio.h>
//告诉C++编译器,add.h包含的内容(C代码)必须用C方式编译
extern "C"
{
#include "add.h"
}
int main()
{
int c = add(1, 2);
printf("c = %d\n", c);
return 0;
}
结果如下:(*.o 目标文件)
通过nm命令,查看add.o目标文件(用C语言编译器编译的)的符号表信息,查看是否有add函数。
保证代码,即被C的编译器编译过,也被C++的编译器编译过。
__cplusplus是C++编译器内置的标准宏定义,可以测试当前的编译器 是不是 C++编译器
__cpluscplus:确保C代码以统一的C方式被编译成目标文件
示例程序:
#include <stdio.h>
//两个#ifdef #endif
#ifdef __cplusplus //如果是C++编译器(__cplusplus测试当前的编译器 是不是 C++编译器)
extern "C" {
#endif
#incldue "add.h"
#ifdef __cplusplus
}
#endif
int main()
{
int c = add(1, 2);
printf("c = %d\n", c);
return 0;
}
结果如下:
C++编译方式将函数名和参数列表编译成目标名
示例程序:
int add(int a, int b)
{
return a + b;
}
int add(int a, int b, int c)
{
return a + b + c;
}
结果如下:
分析:从上图可以知道test.oo的符号表,_Z3addii和_Z3addiii这两个是被编译后的目标函数名(附加信息),ii和iii代表参数的个数,ii表明有两个参数int,iii表明有三个参数int。
注意事项
C++编译器不能以C的方式编译重载函数。
编译方式决定函数名被编译后的目标名。
C++编译方式将函数名和参数列表编译成目标名
小结:
函数重载通过函数名和参数列表,来区分不同的同名函数。
在extern "C"代码块中,不能存在重载函数!!!
函数返回值不能作为函数重载的依据。