C++相对于C语言而言支持函数重载是其极大的一个特点,相信在使用C语言的时候大家如果要写一个实现两个整型数据相加的函数还要写一个浮点型数据相加的函数,那么这两个函数的名字绝对不可以一样,这样无疑在我们使用这个函数的时候增加了复杂性,但是在C++中我们却可以很好的解决这个问题,因为在C++中函数是支持重载的也就是说两个函数的函数名可以一样,这样并不会出现函数名重定义的问题,但是我们在使用的时候也要遵守一些规定,这些规定我们会在接下来的讨论中提到,下面我们就来分析在C++中函数是如何实现函数的重载的。

在这里我们用C语言和C++分别写两个函数,通过函数的符号表来观察函数名在经过编译之后究竟是什么形式的

下面就是我们的测试代码:

 #include<iostream>

 using namespace std;

 int Add(int x, int y)

 {

 int z = ;

 z = x + y;

 return z;

 }

 double Add(double x, double y)

 {

 double z = ;

 z = x + y;

 return z;

 }

 int main()

 {

 cout<<Add(,)<<endl;

 cout<<Add(1.5,3.5)<<endl;

 return ;

 }

在VS2008的编译环境下:

我们生成.map文件,然后可以查看函数在经过编译之后的函数名称为下图所示:

不难发现上图中函数命名的一些规律(当然这个规律只是片面的针对于VS2008编译环境):

1.以“?”开始和以”@Z”结尾

2.函数的名称紧接“?”之后

3.在函数明德后面分别是函数返回值类型修饰符、参数列表中的参数的类型修饰符

下面我们把这个相同的函数改为c语言的代码

代码如下:

 //#include<iostream>

 //using namespace std;

 #include<stdio.h>

 int Add(int x, int y)

 {

 int z = ;

 z = x + y;

 return z;

 }

 double Add(double x, double y)

 {

 double z = ;

 z = x + y;

 return z;

 }

 int main()

 {

 //cout<<Add(1,3)<<endl;

 //cout<<Add(1.5,3.5)<<endl;

 return ;

 }

这时我们编译的话就会出现错误:

这里告诉我们函数名出现重定义

那么这是为什么呢?

这时我们注释掉一个函数然后编译后查看.map文件,查看函数重命名之后的名称

这里我们可以发现函数在编译之后重命名的名称仅仅只是在函数名称的前面加上了一个"_"(下划线),这样我们就不难分析了,C和C++编译的时候对函数的重命名机制是完全不一样的

1.C语言中仅仅只是在函数的名称的前面加上了"_"(下划线)

2.C++有自己的命名修饰规则,他会根据函数的参数列表中变量的类型等进行相应的类型修饰

虽然C++支持函数的重载但是我们在使用的时候也要注意以下几点:

1.函数的重载只是出现在同一作用域,例如假如两个工程里的函数名称相同,但是他们也不是函数的重载

2.函数名相同,函数的参数列表不同,返回值可同可不同,为什么函数返回值可同可不同呢?

这是因为在不同的编译环境下对于函数名称的修饰并不是相同的,下面就是在Linux环境下函数编译后重命名的形式:

仔细观察不难发现在Linux环境下的函数重命名的一些规则:

1.以“_Z”z作为开头,紧随其后的数字是函数名称的单词的个数

2.函数的名称后面有函数的参数列表中参数的类型修饰符,i是int型,d是double型

通过以上的阐述相信大家可以对C++中为什么可以实现函数重载有了清晰的认识,那么我们也就不难回答为什么在C++中调用被C编译过后的函数应该在前面加上 extern "C" 声明了。

这是因为我们当前是处于c++语言环境,这个时候我们如果不指定要调用的那个函数是用C语言编译的函数,那么当前在C++文件中编译时就会报错说是该函数是一个无法解析的外部符号,因为在编译运行的时候我们当前的程序会从符号表中去找相应的函数名,可是C++和C编译后生成的符号表中函数的名是不同的,那么这个函数也就是一个无法解析的外部符号了,但是当你用extern “C” 指明该函数是用C语言编译的函数,那么当前代码在编译运行的时候就会从用C语言编译的那个符号表文件中去查找相应的函数名,这样整个程序的编译运行费也就没有问题了。

C++函数重载实现的原理以及为什么在C++中使用用C语言编译的函数时,要在函数名称前面加上extern "C"声明的更多相关文章

  1. paip.编程语言方法重载实现的原理及python,php,js中实现方法重载

    paip.编程语言方法重载实现的原理及python,php,js中实现方法重载 有些语言,在方法的重载上,形式上不支持函数重载,但可以通过模拟实现.. 主要原理:根据参数个数进行重载,或者使用默认值 ...

  2. 【C++初学者自学笔记二】函数重载(模块一)

    1.概念:同意作用域的一组参数列表不同,函数名相同的函数,这组函数叫函数重载(C语言是不能定义相同名称的函数,但是C++可以允许定义). 2作用:重载函数通常来命名一组功能相似的函数,这样做减少了函数 ...

  3. Javascript函数重载,存在呢—还是存在呢?

    1.What's is 函数重载? );//Here is int 10 print("ten");//Here is string ten } 可以发现在C++中会根据参数的类型 ...

  4. C++学习笔记之模板(1)——从函数重载到函数模板

    一.函数重载 因为函数重载比较容易理解,并且非常有助于我们理解函数模板的意义,所以这里我们先来用一个经典的例子展示为什么要使用函数重载,这比读文字定义有效的多. 现在我们编写一个交换两个int变量值得 ...

  5. 【C++】C++函数重载的总结

    函数重载: 出现在相同作用域中的两个函数,如果具有相同的名字而形参表不同,则称为重载函数(overloaded function).一定要注意函数重载的两个关键词:形参列表和作用域. 任何程序有且仅有 ...

  6. 0607pm克隆&引用类&加载类&面向对象串讲&函数重载

    克隆class Ren{ public $name; public $sex; function __construct($n,$s) { $this->name=$n; $this->s ...

  7. 深入浅出TypeScript(3)- 函数重载和泛型

    面向对象特性中,最根本的就是面向对象的三大基本特征:封装.继承.多态.同时,TypeScript中也存在多态的使用,比如函数重载,今天我们先看一下函数重载以及泛型的概念. 什么是函数重载 简单来说,函 ...

  8. python中不需要函数重载的原因

    函数重载主要是为了解决两个问题: 1.可变参数类型 2.可变参数个数 并且函数重载一个基本的设计原则是,仅仅当两个函数除了参数类型和参数个数不同以外,其功能是完全相同的,此时才使用函数重载,如果两个函 ...

  9. 在C++ 程序中调用被C 编译器编译后的函数,为什么要加extern “C”

    首先,作为extern是C/C++语言中表明函数和全局变量作用范围(可见性)的关键字,该关键字告诉编译器,其声明的函数和变量可以在本模块或其它模块中使用. 通常,在模块的头文件中对本模块提供给其它模块 ...

随机推荐

  1. spring boot入门(一)自己动手搭建spring boot

    spring boot官方文档  http://docs.spring.io/spring-boot/docs/1.2.3.RELEASE/reference/html/index.html 此篇文章 ...

  2. 【PHP】文件写入和读取详解

    文章提纲: 一.实现文件读取和写入的基本思路 二.使用fopen方法打开文件 三.文件读取和文件写入操作 四.使用fclose方法关闭文件 五.文件指针的移动 六.Windows和UNIX下的回车和换 ...

  3. OBS实现直播解决方案【html实现直播】

    项目的需要,要整一个视频直播,但又不想在其他平台那种直播室盗链展示,那我就直接用播放器来实现rtmp流媒体服务器推流吧!没废话,走起 1.你要有一个媒体服务器,暂时用[盘古云],这个还好,算是不错的平 ...

  4. (Unsupported class version number [52.0] (maximum 51.0, Java 1.7))

    遇到类似问题,主要原因是proguard版本只支持到java7,而我使用的是java8. 解决方法是下载最新proguard(支持java 8的版本),然后将下载的文件解压,将libs下jar与and ...

  5. 谈一谈JDK8的函数式编程 (一)

    系列之前我想说的   最近有一段时间没写博客了,这几天回到学校,才闲下来,决定写一写最近学习到的只是,既是为了分享,也是为了巩固.之前看到过一篇调查,文章的数据是学习新知识,光是看只能获得大约5%,然 ...

  6. java虚拟机学习-JVM内存管理:深入Java内存区域与OOM(3)

    概述 Java与C++之间有一堵由内存动态分配和垃圾收集技术所围成的高墙,墙外面的人想进去,墙里面的人却想出来. 对于从事C.C++程序开发的开发人员来说,在内存管理领域,他们即是拥有最高权力的皇帝又 ...

  7. 前端小课堂 js:函数的创建方式及区别

    js 函数的创建大体有这几种方式: -1-函数表达式(函数字面量): 说白了就是把一个函数赋值给了一个变量. var fun1 = function(index){ alert(index); } f ...

  8. 当react框架遇上百度地图

      百度地图官方文档的使用指导是这样说的:在页面中引入<script type="text/javascript" src="http://api.map.baid ...

  9. 使用Eclipse进行Javaweb项目开发时,如何设置外置浏览器Chrome

    使用Eclipse开发Javaweb项目时,在Eclipse中显示页面不是很好,那么如何让它自动打开外置浏览器呢?操作如下

  10. Coursera 机器学习笔记(六)

    主要为第八周内容:聚类(Clustering).降维 聚类是非监督学习中的重要的一类算法.相比之前监督学习中的有标签数据,非监督学习中的是无标签数据.非监督学习的任务是对这些无标签数据根据特征找到内在 ...