重载与指针

下面的函数指针将保存哪个函数的地址:

在给p赋值的时候,我们使用了func,但是这里并没有指明参数,编译器是怎么知道这个func函数指的是第一个func函数呢?

函数重载遇上指针:

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

    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); int main(int argc, char *argv[])
{
int c = ; PFUNC p = func; c = p(); printf("c = %d\n", c); return ;
}

编译运行结果如下:

将19行的返回类型由int改为void或者double,再次编译,结果如下:

三个候选函数都无法匹配p的类型。因为当函数重载遇上函数指针时,编译器会严格匹配函数类型,函数类型包括返回值类型和参数类型。

重载与指针

注意:

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

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

  3、无法直接通过函数名得到重载函数的入口地址

在上一节中,我们直接通过函数名打印了函数地址,这样的话和这里的第三条不就矛盾了吗?

上一节我们对函数名进行了一些转换,如果不转换的话,编译会报错,如下:

编译错误提示我们函数指针没有上下文类型信息。

写上类型转换信息,再次编译,如下:

因为有了明确的类型转换信息,编译器就会根据要转换的目标类型,严格的去匹配函数。严格的匹配就是根据函数的返回值类型和参数类型去匹配,这两个合起来就叫做函数类型。我们也可以说严格的按照函数类型去匹配。

C和C++相互调用:

C++调用C语言写的库:

C++编译器直接编译C语言源码可以直接通过,但是这里我们解决的不是源码编译问题,而是,我们要在C++中利用以前别人别写好的C库函数,这些函数是看不到源码的,它们被编译成了目标文件,我们只能调用。

示例:

编写add.h文件:

 int add(int a, int b);

编写add.c文件:

 #include "add.h"

 int add(int a, int b)

 {

     return a + b;

 }

通过命令gcc -c add.c -o add.o将add.c编译成add.o中间文件。

在main函数中编写C++程序调用add函数(C语言编写的),如下所示:

报错提示我们符号找不到。

通过执行nm  add.o,我们发现add.o文件中确实有add符号。

为了解决这种问题,我们需要强制C++编译器使用C语言的编译方式。

通过extern(extern  "C")关键字可以达到这种目的。

我们将#include "add.h"放进extern "C"中,再次编译运行,结果如下:

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

我们第一个想到的是加上extern "C",但是这个关键字是C++中才有的,C语言中没有这个用法,如果我们在源程序中写上extern "C",然后用C语言编译器编译就会报错。

解决方案如下:

__cplusplus是所有的C++编译器都支持的,标准的宏定义。

实验如下:编写C版本的main函数

用C语言编译器可以编译成功。

注意事项:

示例如下:

可以看到g++编译器编译后目标名里面有参数类型信息。

上述函数以C方式编译的话会直接报错,因为这两个函数得到相同的目标名,因为C语言中没有重载的概念。

小结:

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

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

  extern关键字能够实现C和C++的相互调用,但是extern “C”代码块中绝对不能有重载函数

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

第9课 函数重载分析(下)与C、C++相互调用的更多相关文章

  1. 第七课 GDB调试 (下)

    1序言: 通过前面一节第六课 GDB调试 (下)文章,可以掌握理解了gdb调试:怎么启动.运行,打断点.查看变量.甚至改变变量等的知识,今天来大概讲解下调试bug的类型. 2知识点: 2.1 就像之前 ...

  2. C++基础学习笔记----第四课(函数的重载、C和C++的相互调用)

    本节主要讲了函数重载的主要概念以及使用方法,还有C和C++的相互调用的准则和具体的工程中的使用技巧. 函数重载 1.基本概念 函数重载就是用同一个函数名来定义不同的函数.使用不同的函数参数来搭配同一个 ...

  3. Swift 中的函数(下)

    学习来自<极客学院:Swift中的函数> 工具:Xcode6.4 直接上基础的示例代码,多敲多体会就会有收获:百看不如一敲,一敲就会 import Foundation /******** ...

  4. C++解析(7):函数重载分析

    0.目录 1.重载的概念 2.C++中的函数重载 3.函数默认参数遇上函数重载 4.编译器调用重载函数的准则 5.重载与指针 6.C++和C相互调用 7.小结 1.重载的概念 自然语言中的上下文--你 ...

  5. C++中的函数重载分析(二)

    1,重载与指针: 1,下面的函数指针将保存哪个函数的地址? int func(int x) { return x; } int func(int a, int b) { return a + b; } ...

  6. Linux下进程的同步相互排斥实例——生产者消费者

    linux下的同步和相互排斥 Linux sync_mutex 看的更舒服点的版本号= = https://github.com/Svtter/MyBlog/blob/master/Linux/pth ...

  7. .Net 环境下C# 通过托管C++调用本地C++ Dll文件

     综述 : 本文章介绍.Net 环境下C# 通过托管C++调用本地C++ Dll文件, 示例环境为:VS2010, .Net4.0, Win7. 具体事例为测试C++, C#, 及C#调用本地C++D ...

  8. C&C++——C函数与C++函数相互调用问题

    C C++相互调用 在项目中融合C和C++有时是不可避免的,在调用对方的功能函数的时候,或许会出现这样那样的问题,但只要我的C代码和我的C++代码分别都能成功编译,那其他就不是问题.近来在主程序是C语 ...

  9. .netcore在linux下使用P/invoke方式调用linux动态库

    http://www.mamicode.com/info-detail-2358309.html   .netcore下已经实现了通过p/invoke方式调用linux的动态链接库(*.so)文件 1 ...

随机推荐

  1. Linux下编译安装MySQL5.6

    [准备工作] 所有操作需要在root用户下 本机测试案例系统信息:centos7.3 安装路径:/usr/local/mysql [安装MySQL] 先安装如下依赖包: $ yum -y instal ...

  2. 1040. 有几个PAT(25)

    原题: https://www.patest.cn/contests/pat-b-practise/1040 思路: 先给大家扔个测试PAPAATTPATTT, 人工查一下这段字符串能组成 34个PA ...

  3. 前端基础(jQuery)

    jquery: JS Bootstrap jquery: write less do more jquery对象: Jquery.方法 ======= $.方法 jquery的基础语法:$(selec ...

  4. python中format函数

    python中format函数用于字符串的格式化 通过关键字 1 print('{名字}今天{动作}'.format(名字='陈某某',动作='拍视频'))#通过关键字 2 grade = {'nam ...

  5. presto-cli通过hive查询hdfs

    1.  启动hive metastore 2. 启动hive thrift接口 参考:http://www.cnblogs.com/kisf/p/7497261.html 3. 下载presto se ...

  6. 基于梯度场和Hessian特征值分别获得图像的方向场

    一.​我们想要求的方向场的定义为: 对于任意一点(x,y),该点的方向可以定义为其所在脊线(或谷线)位置的切线方向与水平轴之间的夹角: 将一条直线顺时针或逆时针旋转 180°,直线的方向保持不变. 因 ...

  7. [javaScript]身份证号信息解析

    之前一直在思考是不是该把工作中一些问题写出来(可能是简单的问题),现在的想法是应该写出来这些简单的问题.虽然工作中可能并没有很多特别难的问题让你去解决,因为公司的招人就是根据你的能力来匹配的嘛. 简单 ...

  8. POJ 1625 Censored!(AC自动机->指针版+DP+大数)题解

    题目:给你n个字母,p个模式串,要你写一个长度为m的串,要求这个串不能包含模式串,问你这样的串最多能写几个 思路:dp+AC自动机应该能看出来,万万没想到这题还要加大数...orz 状态转移方程dp[ ...

  9. Data caching per request in Owin application

    Data caching per request in Owin application 解答1 Finally I found OwinRequestScopeContext. Very simpl ...

  10. atcoder ARC092 D - Two Sequences 二分 & 二进制

    今天生日捏,嘻嘻~ 题意:给定A B数组长度为n 求所有 (1<=i,j <=n ) a[i]+b[j] 的异或和. n <=200000  ai bi <=228 这题比赛没 ...