C++函数重载实现的原理以及为什么在C++中使用用C语言编译的函数时,要在函数名称前面加上extern "C"声明
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"声明的更多相关文章
- paip.编程语言方法重载实现的原理及python,php,js中实现方法重载
paip.编程语言方法重载实现的原理及python,php,js中实现方法重载 有些语言,在方法的重载上,形式上不支持函数重载,但可以通过模拟实现.. 主要原理:根据参数个数进行重载,或者使用默认值 ...
- 【C++初学者自学笔记二】函数重载(模块一)
1.概念:同意作用域的一组参数列表不同,函数名相同的函数,这组函数叫函数重载(C语言是不能定义相同名称的函数,但是C++可以允许定义). 2作用:重载函数通常来命名一组功能相似的函数,这样做减少了函数 ...
- Javascript函数重载,存在呢—还是存在呢?
1.What's is 函数重载? );//Here is int 10 print("ten");//Here is string ten } 可以发现在C++中会根据参数的类型 ...
- C++学习笔记之模板(1)——从函数重载到函数模板
一.函数重载 因为函数重载比较容易理解,并且非常有助于我们理解函数模板的意义,所以这里我们先来用一个经典的例子展示为什么要使用函数重载,这比读文字定义有效的多. 现在我们编写一个交换两个int变量值得 ...
- 【C++】C++函数重载的总结
函数重载: 出现在相同作用域中的两个函数,如果具有相同的名字而形参表不同,则称为重载函数(overloaded function).一定要注意函数重载的两个关键词:形参列表和作用域. 任何程序有且仅有 ...
- 0607pm克隆&引用类&加载类&面向对象串讲&函数重载
克隆class Ren{ public $name; public $sex; function __construct($n,$s) { $this->name=$n; $this->s ...
- 深入浅出TypeScript(3)- 函数重载和泛型
面向对象特性中,最根本的就是面向对象的三大基本特征:封装.继承.多态.同时,TypeScript中也存在多态的使用,比如函数重载,今天我们先看一下函数重载以及泛型的概念. 什么是函数重载 简单来说,函 ...
- python中不需要函数重载的原因
函数重载主要是为了解决两个问题: 1.可变参数类型 2.可变参数个数 并且函数重载一个基本的设计原则是,仅仅当两个函数除了参数类型和参数个数不同以外,其功能是完全相同的,此时才使用函数重载,如果两个函 ...
- 在C++ 程序中调用被C 编译器编译后的函数,为什么要加extern “C”
首先,作为extern是C/C++语言中表明函数和全局变量作用范围(可见性)的关键字,该关键字告诉编译器,其声明的函数和变量可以在本模块或其它模块中使用. 通常,在模块的头文件中对本模块提供给其它模块 ...
随机推荐
- springboot(三):Spring boot中Redis的使用
spring boot对常用的数据库支持外,对nosql 数据库也进行了封装自动化. redis介绍 Redis是目前业界使用最广泛的内存数据存储.相比memcached,Redis支持更丰富的数据结 ...
- SPRING AOP ....0 can't find referenced pointcut
下载最新的aspectjweaver就可以了,因为JDK的版本的问题不兼容. //织入点语法 @Pointcut("execution(public * com.frank.dao..*.* ...
- 第6章 影响 MySQL Server 性能的相关因素
前言: 大部分人都一致认为一个数据库应用系统(这里的数据库应用系统概指所有使用数据库的系统)的性能瓶颈最容易出现在数据的操作方面,而数据库应用系统的大部分数据操作都是通过数据库管理软件所提供的相关接口 ...
- (入门篇 NettyNIO开发指南)第三章-Netty入门应用
作为Netty的第一个应用程序,我们依然以第2章的时间服务器为例进行开发,通过Netty版本的时间服务报的开发,让初学者尽快学到如何搭建Netty开发环境和!运行Netty应用程序. 如果你已经熟悉N ...
- javaWeb学习总结(10)- Filter(过滤器)常见应用(3)
一.统一全站字符编码 通过配置参数charset指明使用何种字符编码,以处理Html Form请求参数的中文问题 package me.gacl.web.filter; import java.io. ...
- 详细介绍php中的命名空间
php命名空间的一个最明确的作用是解决重名问题,PHP中不允许两个函数或者类出现相同的名字,否则会产生一个致命的错误.上一章节介绍了什么是php命名空间.php官网已很明确的进行了定义并形象化解释,这 ...
- 初识mysql
一直想试试mysql,但是却一直没有正式的使用过它,也许是因为第一次安装时忘记了root密码,折腾太久留下的后遗症吧,总有点怕怕的.今天第一次使用命令行创建了数据库和数据表,虽然是简单的不能再简单的数 ...
- tomcat产生大量TIME_WAIT连接
http://blog.csdn.net/jiangguilong2000/article/details/12523771
- SG函数和SG定理【详解】
在介绍SG函数和SG定理之前我们先介绍介绍必胜点与必败点吧. 必胜点和必败点的概念: P点:必败点,换而言之,就是谁处于此位置,则在双方操作正确的情况下必败. N点:必胜点 ...
- poi jsp xls
poi jsp xls <%@ page language="java" pageEncoding="UTF-8"import="java.ut ...