关于名称重整(name mangling)、多态性的一些简单介绍
在看GCC源码的时候看到mangles这个单词,于是google了一下。
在面向对象编程语言出现之前,如果你想要打印不同类型的数据,需要写多个方法,例如PrintInteger(int i),PrintString(string s) 和 PrintFloat(float f) 。也就是说, 你必须通过命名来区别行为和数据类型,因为OOP语言出现前任一语言,例如C,不允许你用相同的名字写方法, 即使他们的参数类型不同。
C++的来到实现了方法重载。因此,你可以写多个方法,例如PrintInteger(int i)、PrintString(string s) 和 PrintFloat(float f),编译器自会准确调用特定的Print方法。方法重载被一种称为名称重整(name mangling)的技术所支持,在这种技术中,编译器通过把原方法名称与其参数相结合产生一个独特的内部名字来取代原方法名称。 如此,当你调用Print(1)的时候, 编译器可能在内部用源于参数类型的前缀重命名Print方法,这样一来Print(1)可能就变成 i_Print (1) 。
下面是更详细的例子:
C++编译器实际上将下面这些重载函数:
voidprint(inti);
voidprint(charc);
voidprint(floatf);
voidprint(char* s);
编译为:
_print_int
_print_char
_print_float
_pirnt_string
这样的函数名,来唯一标识每个函数。注:不同的编译器实现可能不一样,但是都是利用这种机制。所以当连接是调用print(3)时,它会去查找_print_int(3)这样的函数。
下面说个题外话,正是因为这点,重载被认为不是多态,多态是运行时动态绑定(“一种接口多种实现”),如果硬要认为重载是多态,它顶多是编译时“多态”。
C++中的变量,编译也类似,如全局变量可能编译g_xx,类变量编译为c_xx等。连接是也是按照这种机制去查找相应的变量 。
方法重载仅是多态性的一种情形。 名称重整是一种支持方法重载的机制。更普遍的情况下,多态性是与继承相联系。 什么是继承呢?继承就是一个新类 (称为子类) 从被继承类(称为父类或超类)取得自身的部分定义同时增加一些自己的新的信息。 如果你在相同的类中重载方法,数据类型必须是不同的。如果你在继承关系下重载方法,子类与父类的方法可能完全相同,而且名称重整器生成同样的重整名称。
举例来说,假设一个超类定义一个Print(int i)方法而一个从它继承的子类也定义了一个Print(int i)方法。当你有一个子类的实例时,运用多态性调用Child.Print(int);而当你产生一个父类的实例时运用多态性调用 Parent.Print(int)。这就是继承多态性:相同的名字和签字但是类却不同。
继承多态性是通过使用一种与名称重整相关的另外一种机制实现的。编译器把方法 放置在一个被称为虚拟方法表(VMT)(其实是一个方法数组)的地方。每一个方法在VMT中都有一个索引, 如此当Print(int)被调用的时候,编译器将被路由到VMT处找寻Print方法和类的内在索引。这样一来,编译器就可以调用正确的方法实现。由编 译器负责管理所有的VMT索引和类偏移量。
简言之,多态性使你能够用非常相似的名字定义许多方法,这里的名字往往都是直观易记的。 OOP编译器自会根据调用者类理解到底该调用哪个方法。
有关name mangling的详细说明可以参考 http://en.wikipedia.org
关于名称重整(name mangling)、多态性的一些简单介绍的更多相关文章
- 《More Effective C++》
new operator申请内存,并调用构造函数: 而operator new只申请内存: new operator会调用operator new来申请内存:operator new可以重写或重载: ...
- 第六章 Hyper-V 2012 R2 的检查点
"检查点"是 Windows Server 2012 R2 中对 Windows Server 2012 及以前版本的 Hyper-V"快照"功能的新称呼.之所 ...
- .NET Core使用gRPC打造服务间通信基础设施
一.什么是RPC rpc(远程过程调用)是一个古老而新颖的名词,他几乎与http协议同时或更早诞生,也是互联网数据传输过程中非常重要的传输机制. 利用这种传输机制,不同进程(或服务)间像调用本地进程中 ...
- HTTP和RPC是现代微服务架构,HTTP和RPC是现代微服务架构
.NET Core使用gRPC打造服务间通信基础设施 一.什么是RPC rpc(远程过程调用)是一个古老而新颖的名词,他几乎与http协议同时或更早诞生,也是互联网数据传输过程中非常重要的传输机制 ...
- 使用gRPC打造服务间通信基础设施
一.什么是RPC rpc(远程过程调用)是一个古老而新颖的名词,他几乎与http协议同时或更早诞生,也是互联网数据传输过程中非常重要的传输机制. 利用这种传输机制,不同进程(或服务)间像调用本地进程中 ...
- laravel框架基础知识总结
一.laravel简介 laravel是一套优雅简介的PHP开发框架,受欢迎程度非常之高,功能强大,工具齐全:以下是本人在学习过程中记录的laravel比较基础的资料,权当学习笔记,请大神们多多指教 ...
- Hive UDF,就这
摘要:Hive UDF是什么?有什么用?怎么用?什么原理?本文从UDF使用入手,简要介绍相关源码,UDF从零开始. 本文分享自华为云社区<Hive UDF,就这>,作者:汤忒撒. Hive ...
- C++中的名字重整技术
C++ 一直为人诟病之一的原因是他的二进制模块兼容性不好,即ABI(Application Binary Interface)问题.对于同一源代码,不同编译器,甚至同一编译器不同版本都不兼容,其编译出 ...
- 【Java学习笔记之二十四】对Java多态性的一点理解
面向对象编程有三大特性:封装.继承.多态. 封装隐藏了类的内部实现机制,可以在不影响使用的情况下改变类的内部结构,同时也保护了数据.对外界而已它的内部细节是隐藏的,暴露给外界的只是它的访问方法. 继承 ...
随机推荐
- UVA 10972 RevolC FaeLoN(边连通分量)
坑了我一天的题目..跑了20ms挂了,就知道有个小毛病= = 无向图转有向图判强连通. 首先要知道什么样的无向图可以转化为强连通图?连通分量(环)自然是可以的:那么扩大范围(存在割顶),发现点连通分量 ...
- Java [Leetcode 172]Factorial Trailing Zeroes
题目描述: Given an integer n, return the number of trailing zeroes in n!. Note: Your solution should be ...
- Android中FragmentPagerAdapter对Fragment的缓存(二)
上一篇我们谈到了,当应用程序恢复时,由于FragmentPagerAdapter对Fragment进行了缓存的读取,导致其并未使用在Activity中新创建的Fragment实例.今天我们来看如何解决 ...
- [Everyday Mathematics]20150202
设 $f:\bbR^2\to \bbR$ 为连续函数, 且满足条件 $$\bex f(x+1,y)=f(x,y+1)=f(x,y),\quad\forall\ (x,y)\in \bbR^2. \ee ...
- [Everyday Mathematics]20150129
计算下列积分 $$\bex \int_a^b (x-a)^2(b-x)^3\rd x. \eex$$
- UI篇--布局问题
1.android:layout_marginRight 不起作用解决方法 今天想在RelativeLayout的左右分别放上一个按钮, 左边按钮用marginLeft="10dp" ...
- Dev gridControl 按回车增加一行
将NewItemRowPosition属性设置为Top或Bottom, 在这样的新行中输入数据后,会自动添加到绑定的数据源中的, 如果你希望在按回车时焦点跳至下一列, 只需要设置GridView的Op ...
- IOS 类别与扩展的区别 (category & extensions)
类别 .h @interface NSString(XXXXXX) -(NSInteger)getLen; @end .m @implementation NSString(XXXXXX) -(NSI ...
- ios游戏开发--cocos2d学习(1)
学习cocos2d需要一定的编程基础,最好了解objective-c的语法.至于下载和安装的过程网上有很多,这里不多介绍,直接进入项目的学习. 创建一个cocos2d项目,直接运行,效果如图: 左下角 ...
- Socket异步发送的同步控制
在网络通信中,我们使用Socket异步发送数据,但在客户端,往往是需要等待服务器的返回结果后(握手过程)再往下执行,这就涉及到同步控制了,在多次的实现中,使用AutoResetEvent,实现不,即有 ...