1、        概念

首先,什么是绑定?( what`s the definition of binding? )

c++编程思想上有说到:

Connecting a function call to a function body is called binding.(将函数体和函数调用关联起来,就叫绑定)

然后,那么什么是早绑定?(Early binding)

When binding is performed before the program is run (by the compiler and linker), it' s called early binding
在程序运行之前(也就是编译和链接时),执行的绑定是早绑定。

然后,什么是迟绑定?(late binding)

late binding, which means the binding occurs at runtime, based on the type of the object.
When a language implements late binding, there must be some mechanism to determine the

type of the object at runtime and call the appropriate member function

迟绑定发生在运行时,基于不同类型的对象。当一种语言实现迟绑定时,必须有某种机制确定对象的具体类型然后调用合适的成员函数。

2、         结论

2.1对于含有虚拟函数的类来说:

Ø        虚函数表是与类关联的,也就是说,一个类只有一张虚函数表。(从这个方面上说,虚函数类似于类的静态函数)(父类有一个Vtable,子类也有一个Vtable)

Ø        VTable中虚函数的位置是由基类决定的,所以,哪怕你在派生类中不是按基类的顺序来重写虚函数,派生类的VTable中虚函数的存放顺序和基类的也是一样的。

Ø        虚函数指针VPtr是与对象关联的,每个对象都有一个虚函数指针,但是,同类的对象的虚函数指针的值是相同的。因为都指向该类的虚函数表。

Ø        虚函数指针VPtr的值是在调用构造函数时进行初始化的(自动完成)。

2.2 C++迟绑定实现机理流程(编译器都是类似于此种方式实现的):
(1)为每个含有虚函数的类(基类以及派生类)都创建一张虚函数表(VTable,存储于常量区),依次存放虚函数的地址。对于派生类来说,如果没有重写其基类的虚函数,那么,将会在VTable中存放基类的虚函数地址。
(2)为每个含有虚函数的类的对象,创建一个指针(VPtr),指向这个类的虚函数表(所以说,同类对象的VPtr的值是一样的[*VPtr相同,但VPtr不同],也就是说,虚函数,在这一点上,类似于类的static函数,是所有对象共有的。)(此过程发生在运行期自动调用构造函数的过程中)
(3)通过强制转换将派生类对象的地址/引用 赋给基类指针/变量(也就是向上类型转换UpCasting)(此步决定了基类指针首先寻址的虚函数表,也就是现在派生类的虚函数表中寻址,如果在派生类的虚函数表中没有找到此虚函数,则向上一级基类的虚函数表中寻找此虚函数,依次类推。由此可见,虽然代码相同,却实现了调用不同类函数的目的,也就是多态)

(4)然后,通过基类指针/引用对象 来调用虚函数(即:polymorphic call),就会通过此时基类对象的VPtr指针在所指向虚函数表中寻址(一般是从表头地址开始,加上一定的偏移量)找到相应的函数地址,也就是之前派生类VPtr指针指向的虚函数表的函数地址。

 

2.3晚绑定原理

编译器对每个包含虚函数的类创建一个表(称为V TA B L E)。在V TA B L E中,编译器放置特定类的虚函数地址。在每个带有虚函数的类中,编译器秘密地置一指针,称为v p o i n t e r(缩写为V P T R),指向这个对象的V TA B L E。通过基类指针做虚函数调用时(也就是做多态调用时),编译器静态地插入取得这个V P T R,并在V TA B L E表中查找函数地址的代码,这样就能调用正确的函数使晚捆绑发生。为每个类设置V TA B L E(编译期)、初始化V P T R(运行期构造函数中)、为虚函数调用插入代码(运行期多态调用时),所有这些都是自动发生的,所以我们不必担心这些。利用虚函数,这个对象的合适的函数就能被调用,哪怕在编译器还不知道这个对象的特定类型的情况下。(《C++编程思想》)

2.4早绑定和晚绑定优缺点

早绑定,晚绑定,早晚都要绑定。绑定指在对象和其类型间建立关联的过程。

早绑定指在对象申明的时候就和他的类型建立了关联。

晚绑定是指我们的代码在运行时再检查对象是否提供了我们所需要的方法和属性。

很多人说C#和Java是早绑定的,javascript,python是迟绑定的,其实这个说法并不全对

一方面,C#和Java是强类型的,在变量声明的时候就说明了类型,从这里来讲当然是早绑定的,于是我们才能在IDE中享受代码提示带来的方便,因为ide通过你的申明就能知道你的对象是什么类型,具有什么方法和属性,然后提示给你,同时编译的时候也可以帮你检查许多类型转换的错误.

另一方面:无论C#和Java在实现他们很重要的一个功能:多态的时候,都是用晚绑定,比如你的父类中定义了virtual的方法,那么这个方法可能会在你的子类中重载,具体你用什么子类,是变量申明时所不知道的,在C++编译器会在编译的时候为这些类加上一个指针,指针指向一个虚表,虚表中存在着真实的函数,这个是就是一个晚绑定了

早绑定的优点是:

Ø        编译效率

Ø        代码提示(代码智能感知)

Ø        编译时类型检查

晚绑定的优点是:

Ø        不用申明类型

Ø        对象类型可以随时更改

参考资料:

http://blog.csdn.net/faithmy509/archive/2009/05/21/4207625.aspx

http://www.cnblogs.com/yizhu2000/archive/2007/07/12/815628.html

http://blog.sina.com.cn/s/blog_63797eb20100gni8.html(C++ 多态迟绑定原理)

迟绑定早绑定,迟早都要绑定相关推荐

  1. # 命令行新建 job 错误: ORA-01008 并非所有变量都已绑定 。

    # 命令行新建 job 错误: ORA-01008 并非所有变量都已绑定 . 1.改正前代码: DECLARE job NUMBER; begin sys.dbms_job.submit(job =& ...

  2. Ora-01008错误:oracle 并非所有变量都已绑定的原因

    begin test.test(a => 1, b => :603); end; 执行的时候报错: Ora-01008错误:oracle 并非所有变量都已绑定 原因是b => :60 ...

  3. 由手机号绑定的账号,都应设置更换手机号功能

    我是iOS开发,最近更换了手机号.除了银行卡预留手机号需要换掉外,经常用的微信,qq,支付宝等用手机号绑定的app,都需要一一置换手机号. 支付宝,微信的帐户都为手机号,登录后,在设置处,都有修改手机 ...

  4. 解决ORA-01008: 并非所有变量都已绑定(详解问题所在)

    将executeUpdate(sql)或executeQuery(sql)括号中的sql删除. 问题代码: public static void main(String[] args) throws ...

  5. ORA-01008: 并非所有变量都已绑定

    ORA-01008: 并非所有变量都已绑定  DECLARE job NUMBER; begin   sys.dbms_job.submit(job =>:job,                ...

  6. oracle+并非所有变量,ORA-01008:并非所有变量都已绑定异常错误汇总解决方案

    一.异常错误介绍 我们在使用oracle数据库做程序开发时,一般都会使用plsql做客户端连接查询工具,在写sql语句时plsql经常会报并非所有变量都已绑定01008这样类似的异常错误,通常我们程序 ...

  7. Oracle 并非所有变量都已绑定

    begin test.test(a => 1, b => :603); end; 执行的时候报错: Ora-01008错误:Oracle?并非所有变量都已绑定 原因是??b => : ...

  8. ORA-01008:nbsp;并非所有变量都已绑定

    java.sql.SQLException: ORA-01008: 并非所有变量都已绑定 此异常为sql异常,我遇到的时候看java代码如下 public void savegdzcysxx(Gdzc ...

  9. oracle定时任务报“并非所有变量都已经绑定”以及创建,删除等

    -- 查询该存储过程的定时任务 select job, next_date, next_sec, failures,what, broken from dba_jobs where what like ...

最新文章

  1. 51nod 1126 求递推序列的第N项 思路:递推模拟,求循环节。详细注释
  2. php正则学习,php中正则表达式的学习及应用
  3. jdk 安装_Linux安装JDK操作手册
  4. python把dict转成json_Python dict(或对象)与json之间的互相转化
  5. (转载)Hadoop -- Map-Reduce入门
  6. 时隔二十年,《程序员修炼之道》出第二版了!
  7. Java基础0309
  8. Prometheus 和 Alertmanager实战配置
  9. 二叉树遍历——递归算法
  10. 文件的输入法程序的字符编码
  11. MATLAB | 全网唯一 ,MATLAB绘制阴影柱状图(填充斜线)
  12. Android 反编译修改包名、重新签名、更换app名称
  13. BIRD 与 BGP 的新手开场 --转
  14. 第六届ACM省赛总结--吕云飞
  15. 是非人生——一个菜鸟程序员的5年人生路
  16. Es6里面的Set和Map集合
  17. 超全总线控制方式总结
  18. 苹果手机服务器找不到,电脑找不到苹果手机热点
  19. SDP: 会话描述协议(Session Description Protocol)
  20. 【uniapp】页面下拉刷新

热门文章

  1. 第二行代码第三章笔记
  2. ROS与navigation——ACML参数配置
  3. 系统静态分析建模(类图)
  4. Tomcat 性能监控指南
  5. ansible七种武器
  6. 【原作者:byxdaz】Android系统介绍与框架
  7. 常见的浏览器兼容问题: html 方面
  8. speedoffice(Excel)如何去除文本框的边框?
  9. 如何用沉浸式叙事做品牌营销|技术就是沉浸式的全部吗?
  10. Excel批量导入图片:1列为图片,1列为备注