带你从编码角度分析C++重载原理

目录
  • 什么是函数重载
  • 代码分析
  • 总结

什么是函数重载

函数重载的即是在相同作用域中的多个函数,它们具有相同的名字而型参不同,但是在C++中他们可以正常编译,不会因为同名而出现error。这是因为在C++利用了name mangling(倾扎)技术,在对程序编译之前,编译器将会用参数个数和参数类型对每一个函数标识符进行专门编码。

接下来我们将会使用C++和C中分别实现代码,使用nm命令来查看可执行文件的中编译后的函数名是怎样的?

代码分析

我们借用如下代码分别使用c和c++的编译器编译运行,来进行分析。

int Add(int a, int b){
    return a+b;
}
float Add(float a, float b){
    return a+b;
}
int main(){
    int c = Add(10, 5);
}

C语言分析:

我们将上述代码放入overload.c的文件中,使用c的编译器进行分析,将会出现报错如下:

这就是因为在我们的程序中有两个同名的函数,也证明了C语言无法实现重载。那么我们修改这段代码,去掉一个Add函数,具体代码如下:

int Add(int a, int b){
    return a+b;
}
int main(){
    int c = Add(10, 5);
}

编译通过,生成可执行文件a.out,我们使用nm 可执行文件名查询该可执行文件中编译过的函数名如下:

我们会发现在C的编译器下,编译过的函数名和我们程序中自定义的函数名是相同的。接下来我们使用C++的编译器来进行编译。

C++分析

将不做修改的代码放入一个overload.cpp文件中,使用C++编译器进行编译,会发现这次不会报错,这也是C++中函数重载的结果,我们直接使用nm来查看编译过的函数名。

我们会发现函数名发生了改变,这就是C++的编译器对程序中的函数中的每一个函数名进行了编码,其中的_z是规定前缀,3是函数名的个数,i是参数列表类型int的首字母。这个过程我们称作“名字改编”或“名字修饰”,类型安全的连接使得程序能够调用合适的重载函数并保证了参数传递的一致性。

注意:main函数不会进行名字改编。

总结

本篇文章就到这里了,希望能够给你带来帮助,也希望您能够多多关注我们的更多内容!

(0)

相关推荐

  • C++运算符重载图文详解

    目录 1. 运算符重载 1.1 运算符重载为普通函数 1.2 运算符重载为成员函数 2. 赋值运算符=的重载 2.1浅复制与深复制 2.2返回值的讨论 3. 动态可变长度数组 总结 1. 运算符重载 C++的运算符只能用于基本的数据类型 表达形式 返回值类型 operator 运算符 (形参表) { ... } 1.1 运算符重载为普通函数 1.2 运算符重载为成员函数 2. 赋值运算符=的重载 当赋值运算符两边的类型不匹配,比如int类型赋值给Complex类型,在这种情况下,就需要重载赋值运

  • C++ 函数重载详情介绍

    文章转自微信公众号:Coder梁(ID:Coder_LT) 函数重载 函数重载还有一个别名叫函数多态,其实我个人感觉函数多态这个名字更好理解更恰当一些. 函数多态是C++在C语言基础上的新特性,它可以让我们使用多个同名函数.当然这些同名函数的参数是要有区别的,我们在函数调用的时候,编译器会自动根据我们传入的参数,从多个同名函数当中找到我们调用的那一个.和面向对象里的多态的概念很接近. 我们在定义函数的时候,编译器只会查看参数的数目和类型,而不会理会参数的名称.只要参数的数量以及类型不完全相同,就

  • 聊聊C++ 运算符重载知识

    前言 1.运算符重载是一种形式的C++多态. 2.重载运算符可以使代码看起来更加自然. 回顾类 在正常构造类的时候,有些成员方法可以不用写出来,例如在这样一个表示时间的类中,拷贝构造函数只是浅拷贝,和系统默认的步骤是一样的,可以不用写了. 同样,析构函数如果在对象死亡之前没有必须要做的事情,也可以不用写. 所以在下面的例子中,拷贝构造和析构函数可以省略. class Time { public: Time(); Time(const Time& src) { _hour = src._hour;

  • C++之函数的重载

    目录 一.C++ 函数重载 1.重载规则 2.匹配原则 3.重载底层实现 4.extern "C" 总结 一.C++ 函数重载 C++ 致力于简化编程,能过函数重名来达到简化编程的目的 1.重载规则 1.函数名相同 2.参数的个数不同,类型不同,顺序不同,都可以构成重载 3.返回值类型必须相同,不同则不可以构成重载 例如: void func(int a); //ok void func(char a); //ok void func(char a,int b); //ok void

  • C++模板重载

    目录 1.重载模板 2.问题  文章转自 公众号:Coder梁(ID:Coder_LT) 1.重载模板 函数模板可以使得同一个函数对不同类型使用,非常地方便.但有的时候类型不同,只是通过模板是没办法解决的, 可能逻辑上也会有所区别,这个时候只是使用模板是无法解决的. 为了满足这种需求,我们可以像是重载函数那样重载模板.和常规的函数一样,重载的模板的函数特征,也就是入参的数量和类型必须有所不同. 举个例子:比如我们之前定义了一个函数模板用来交换两个变量的值.如果我们要交换的不只是变量,而是两个数组

  • 带你从编码角度分析C++重载原理

    目录 什么是函数重载 代码分析 总结 什么是函数重载 函数重载的即是在相同作用域中的多个函数,它们具有相同的名字而型参不同,但是在C++中他们可以正常编译,不会因为同名而出现error.这是因为在C++利用了name mangling(倾扎)技术,在对程序编译之前,编译器将会用参数个数和参数类型对每一个函数标识符进行专门编码. 接下来我们将会使用C++和C中分别实现代码,使用nm命令来查看可执行文件的中编译后的函数名是怎样的? 代码分析 我们借用如下代码分别使用c和c++的编译器编译运行,来进行

  • Java面试题 从源码角度分析HashSet实现原理

    面试官:请问HashSet有哪些特点? 应聘者:HashSet实现自set接口,set集合中元素无序且不能重复: 面试官:那么HashSet 如何保证元素不重复? 应聘者:因为HashSet底层是基于HashMap实现的,当你new一个HashSet时候,实际上是new了一个map,执行add方法时,实际上调用map的put方法,value始终是PRESENT,所以根据HashMap的一个特性: 将一个key-value对放入HashMap中时,首先根据key的hashCode()返回值决定该E

  • Java源码角度分析HashMap用法

    -HashMap- 优点:超级快速的查询速度,时间复杂度可以达到O(1)的数据结构非HashMap莫属.动态的可变长存储数据(相对于数组而言). 缺点:需要额外计算一次hash值,如果处理不当会占用额外的空间. -HashMap如何使用- 平时我们使用hashmap如下 Map<Integer,String> maps=new HashMap<Integer,String>(); maps.put(1, "a"); maps.put(2, "b&quo

  • 从数据结构的角度分析 for each in 比 for in 快的多

    之前听说火狐的JS引擎支持for each in的语法,例如下述的代码: 复制代码 代码如下: var arr = [10,20,30,40,50];for each(var k in arr)console.log(k); 即可直接遍历出arr数组的内容. 由于只有FireFox才支持,所以几乎所有的JS代码都不用这一特征. 不过在ActionScript里天生就支持for each的语法,不论Array还是Vector,还是Dictionary,只要是可枚举的对象都可以for in和for

  • 从源码角度分析Android的消息机制

    前言 说到Android的消息机制,那么主要的就是指的Handler的运行机制.其中包括MessageQueue以及Looper的工作过程. 在开始正文之前,先抛出两个问题: 为什么更新UI的操作要在主线程中进行? Android中为什么主线程不会因为Looper.loop()里的死循环卡死? UI线程的判断是在ViewRootImpl中的checkThread方法中完成的. 对于第一个问题,这里给一个简单的回答: 如果可以在子线程中修改UI,多线程的并发访问可能会导致UI控件的不可预期性,采用

  • 浅谈JVM系列之从汇编角度分析NullCheck

    一个普通的virtual call 我们来分析一下在方法中调用list.add方法的例子: public class TestNull { public static void main(String[] args) throws InterruptedException { List<String> list= new ArrayList(); list.add("www.flydean.com"); for (int i = 0; i < 10000; i++)

  • 从架构思维角度分析高并发下幂等性解决方案

    目录 1 背景 2 幂等性概念 3 幂等性问题的常见解决方案 3.1 查询操作和删除操作 3.2 使用唯一索引 或者唯一组合索引 3.3 token机制 3.4 悲观锁 3.5 乐观锁 3.6 分布式锁 3.7  select + insert 3.8 状态机幂等 3.9 保证Api接口的幂等性 4 会议室的解决方案 5 总结 1 背景 我们的云办公系统有一个会议预定模块,每个月最后一个工作日的下午三点,会启动对下个月会议室的可用预定. 公司的 会议室大约200个,但是需求量远不止于此,所以会形

  • 从架构思维角度分析分布式锁方案

    目录 1 介绍 2 关于分布式锁 3 分布式锁的实现方案 3.1  基于数据库实现 3.1.1 乐观锁的实现方式 3.1.2 悲观锁的实现方式 3.1.3 数据库锁的优缺点 3.2基于Redis实现 3.2.1 基于缓存实现分布式锁 3.2.2缓存实现分布式锁的优缺点 3.3 基于Zookeeper实现 3.3.1 实现过程 3.3.2 zk实现分布式锁的优缺点 3.4 三种方案的对比总结 1 介绍 前面的文章我们介绍了分布式系统和它的CAP原理:一致性(Consistency).可用性(Ava

  • 详细分析jsonp的原理和实现方式

    针对跨域问题,本文主要给大家详细分析一下jsonp的原理,希望能够给你提供到帮助. 详细分析jsonp的原理和实现方式 一:跨域问题. 二,跨域产生的原因 Js是不能跨域请求.出于安全考虑,js设计时不可以跨域. 什么是跨域: 1.域名不同时. 2.域名相同,端口不同. 只有域名相同.端口相同时,才可以访问. 可以使用jsonp解决跨域问题. 三,跨域失败的案例 3.1,同源策略 首先基于安全的原因,浏览器是存在同源策略这个机制的,同源策略阻止从一个源加载的文档或脚本获取或设置另一个源加载的文档

  • 详解Vue-Router源码分析路由实现原理

    深入Vue-Router源码分析路由实现原理 使用Vue开发SPA应用,离不开vue-router,那么vue和vue-router是如何协作运行的呢,下面从使用的角度,大白话帮大家一步步梳理下vue-router的整个实现流程. 到发文时使用的版本是: - vue (v2.5.0) - vue-router (v3.0.1) 一.vue-router 源码结构 github 地址:https://github.com/vuejs/vue-router components下是两个组件<rout

随机推荐