09-函数重载分析(下)

蹲街弑〆低调 提交于 2020-02-15 23:53:13

注:博客中内容主要来自《狄泰软件学院》,博客仅当私人笔记使用。

测试环境:Ubuntu 10.10

GCC版本:4.4.5

 

一、重载与指针

1)下面的函数指针将保存在哪个函数的地址?

2)函数重载遇上函数指针

 - 将重载函数名赋值给函数指针

   1.根据重载规则挑选与函数指针参数列表一致的候选者

   2.严格匹配候选者的函数类型与函数指针的函数类型 

编程实验
函数重载VS函数指针
9-1.cpp
/*
这个例子是为了证明:
 - 重载函数名赋值给指针时
1.根据重载规则挑选与函数指针参数列表一致的候选者
2.严格匹配候选者的函数类型与函数指针的函数类型
*/

#include <stdio.h>
#include <string.h>

int func(int x)
{
    return x;
}

int func(int a, int b)	//不满足条件1
{
    return a + b;
}

int func(const char* s)	//不满足条件2
{
    return strlen(s);
}

typedef int(*PFUNC)(int a);
//typedef void(*PFUNC)(int a);	//函数类型与定义的函数不相同

int main(int argc, char *argv[])
{
    int c = 0;

    PFUNC p = func;
        
    c = p(1);   
    
    printf("c = %d\n", c);

    return 0;
}

操作:

1) g++ 9-1.cpp -o 9-1.out编译正确,打印结果:

c = 1

分析:证明调用了int func(int x)

 

2) 修改代码:

#include <stdio.h>
#include <string.h>

int func(int x)
{
    return x;
}

int func(int a, int b)	//不满足条件1
{
    return a + b;
}

int func(const char* s)	//不满足条件2
{
    return strlen(s);
}

typedef void(*PFUNC)(int a);	 //函数类型与定义的函数不相同

int main(int argc, char *argv[])
{
    int c = 0;

    PFUNC p = func;
        
    c = p(1);   
    
    printf("c = %d\n", c);

    return 0;
}

g++ 9-1.cpp -o 9-1.out编译报错:

9-1.cpp:25:12: error: no matched converting function 'func' to type 'PFUNC {aka void (*)(int)}'
    PFUNC p = func;
错误:转换'func'函数没法匹配类型'PFUNC'函数

3)注意

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

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

   -   无法直接通过函数名得到重载函数的入口地址(还需要指明函数类型)

 

二、C++ 和 C相互调用

1)实际工程中C++ 和 C代码相互调用是不可避免的

2)C++编译器能够兼容C语言的编译方式

3)C++编译器会优先使用C++编译的方式

4)extern关键字能强制让C++编译器进行C方式的编译

extern "C" //在C++里可以用
{
      // do C-style compilation here
}

 

编程实验
C++调用C函数
9-2
main.cpp
#include <stdio.h>

#ifdef __cplusplus
extern "C" {
#endif

#include "add.h"

#ifdef __cplusplus
}
#endif

int main()
{
    int c = add(1, 2);
    
    printf("c = %d\n", c);
    
    return 0;
}

add.h

int add(int a, int b);


add.c
#include "add.h"

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

操作:

1) gcc -c add.c -o add.o编译出add.o文件,再用g++ main.cpp add.o编译。

nm打开add.o文件查看是否有add:

00000000 T add

运行结果:

c = 3

 

三、问题

       如何保证一段C代码只会以C的方式被编译?

 

解决方案:

1)__cplusplus是C++编译器内置的标准宏定义

2)__cplusplus的意义

  - 确保C代码以统一的C方式被编译成目标文件

#ifdef __cplusplus    //如果是C++编译器执行
extern "C"{
#endif

// C-Style Compilation

#ifdef __cplusplus
}
#endif

 

四、注意事项:

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

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

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

     - C编译方式只将函数名作为目标名进行编译

 

小结:

1)函数重载是C++对C的一个重要升级

2)函数重载通过函数参数列表区分不同的同名函数

3)extern关键字能够实现C和C++的相互调用

4)编译方式决定符号表中的函数名的最终目标名

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!