8、函数重载分析(下)

1、重载与指针

  • 下面的函数指针将保存哪个函数的地址?
    在这里插入图片描述
typedef int(*PFUNC)(int a)
int c = 0;
PFUNC p = func;
c = p(1);

很明显就是第一个函数。

  • 函数重载遇上函数指针
    — 将重载函数名赋值给函数指针时(上面的第三条语句)
    1、根据重载规则挑选与函数指针参数列表一致的候选者
    2、严格匹配候选者的函数类型与函数指针的函数类型
#include <stdio.h>
#include <string.h>

int func(int x)
{
	return x;
}
int func(int a, int b)
{
	return a + b;
}
int func(const char* s)
{
	return strlen(s);
}
typedef int(*PFUNC)(int a);
//typedef void(*PFUNC)(int a);
int main()
{

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

在这里插入图片描述
如果一旦在第17行代码改变为没有的函数类型,就会报错,所以要严格匹配。
在这里插入图片描述

  • 注意:
    — 函数重载必然发生在同一个作用域中
    — 编译器需要用参数列表函数类型进行函数选择
    无法直接通过函数名得到重载函数的入口地址
    如果不根据函数指针的类型或者参数列表,我们是得不到重载函数的地址,仅仅通过函数名根本办不到。
    回顾上一章的最后一个程序,如果我们改一下代码
#include <stdio.h>
#include <string.h>
int add(int a, int b)
{
	return a + b;
}
int add(int a, int b, int c)
{
	return a + b + c;
}

int main()
{
	printf("%p\n", add);
	printf("%p\n", add);

	return 0;
}

在代码的14行和15行,如果我们直接用函数名去打印函数的入口地址会出现什么情况?
在这里插入图片描述
很明显会出错,所以函数的重载我们不能通过函数名得到函数的入口地址。

以前C语言里面没有函数重载的概念,所以在C语言我们可以用函数名来获取函数的入口地址。

#include <stdio.h>

int add(int a, int b)
{
	return a + b;
}
int main()
{
	printf("%p\n", add);
	return 0;
}

在这里插入图片描述

2、C++和C相互调用

  • 实际工程中C++和C代码相互调用是不可避免的
  • C++编译器能够兼容C语言的编译方式
  • C++编译器会优先使用C++编译器的方式
  • extern 关键字能强制让C++编译器进行C方式的编译
extern "C"
{
	//do C-style compilation here
}

什么情况下用extern"C"?就是我们的C++程序里面如果要加入C程序,但是C++编译器是以C++的方式把它编译出来,未免会有偏差,所以我们可以在我们想要用C方式编译的前面写上extern"C",然后用大括号扩住。

举例:在Linux C环境下,先写两个文件
add.c

#include "add.h"
int add(int a,int b)
{
	return a+b;
}

add.h

int add(int a,int b);

在Linux下编译成add.0的文件
然后写一个C++程序
main.cpp

#include <stdio,h>
#include <add.h>
int main()
{
	int c = add(1,2);
	printf("c = %d\n",c);
	return 0;
}

用命令行编译g++ main.cpp add.o,发现会报错,这是为什么呢,因为 main 文件是C++编译器用C++方式编译,但是头文件是一段C语言代码,所以我们应该把头文件用C语言的方式编译,所以:

#include <stdio.h>
extern"C"
{
	#include "add.h"
}
int main()
{
	int c = add(1,2);
	printf("c = %d\n",c);
	return 0;
}

这样就是对的。

问题:如何保证一段C代码只会以C的方式被编译?
extern"C"是C++里面独有的,C语言里面不支持extern"C"的用法。所以在C语言里面extern“C”就会报错

解决方案:

  • __cplusplus是C++编译器内置的标准宏定义(C语言编译器内部没有这个宏)
  • __cplusplus的意义
    — 确保C代码以统一的C方式被编译成目标文件
#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;
}

小结:

  • 函数重载是C++对C的一个重要升级
  • 函数重载通过函数参数列表 区分 不同的 同名函数
  • extern关键字能够实现C和C++的相互调用
  • 编译方式决定符号表中的函数名的最终目标名
    最后一句话是什么意思呢,就是说一个函数如果C语言编译方式得到的目标名是一种,但是这个函数的重载函数以C++编译方式编译得到的目标名是不同的,所以编译方式决定了最终的目标名。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值