天天看点

C++深度解析 函数重载分析---函数指针,函数重载,C++和C相互调用(8)函数指针函数重载  VS  函数指针C++和C相互调用保证代码,即被C的编译器编译过,也被C++的编译器编译过。 C++编译方式将函数名和参数列表编译成目标名注意事项小结:

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相互调用(8)函数指针函数重载  VS  函数指针C++和C相互调用保证代码,即被C的编译器编译过,也被C++的编译器编译过。 C++编译方式将函数名和参数列表编译成目标名注意事项小结:

从上述例子,注意:

函数重载必然发生在同一个作用域中。

编译器需要用参数列表或函数类型进行函数选择。

无法直接通过函数名得到重载函数的入口地址(参考上一章节的最后一个例子!!!!)

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 目标文件)

C++深度解析 函数重载分析---函数指针,函数重载,C++和C相互调用(8)函数指针函数重载  VS  函数指针C++和C相互调用保证代码,即被C的编译器编译过,也被C++的编译器编译过。 C++编译方式将函数名和参数列表编译成目标名注意事项小结:
C++深度解析 函数重载分析---函数指针,函数重载,C++和C相互调用(8)函数指针函数重载  VS  函数指针C++和C相互调用保证代码,即被C的编译器编译过,也被C++的编译器编译过。 C++编译方式将函数名和参数列表编译成目标名注意事项小结:

通过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++深度解析 函数重载分析---函数指针,函数重载,C++和C相互调用(8)函数指针函数重载  VS  函数指针C++和C相互调用保证代码,即被C的编译器编译过,也被C++的编译器编译过。 C++编译方式将函数名和参数列表编译成目标名注意事项小结:

C++编译方式将函数名和参数列表编译成目标名

示例程序:

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

int add(int a, int b, int c)
{
    return a + b + c;
}
           

结果如下:

C++深度解析 函数重载分析---函数指针,函数重载,C++和C相互调用(8)函数指针函数重载  VS  函数指针C++和C相互调用保证代码,即被C的编译器编译过,也被C++的编译器编译过。 C++编译方式将函数名和参数列表编译成目标名注意事项小结:

分析:从上图可以知道test.oo的符号表,_Z3addii和_Z3addiii这两个是被编译后的目标函数名(附加信息),ii和iii代表参数的个数,ii表明有两个参数int,iii表明有三个参数int。

注意事项

C++编译器不能以C的方式编译重载函数。

编译方式决定函数名被编译后的目标名。

C++编译方式将函数名和参数列表编译成目标名

小结:

函数重载通过函数名和参数列表,来区分不同的同名函数。

在extern "C"代码块中,不能存在重载函数!!!

函数返回值不能作为函数重载的依据。

继续阅读