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. NVIDIA深度学习Tensor Core性能解析(下)
  2. echo向文件中写入
  3. HDU2044 一只小蜜蜂…(简单递推)
  4. python源码精要(6)-CPython编译标志
  5. ArrayList LinkedList与HashMap 实现原理
  6. 2013eoe移动开发者大会圆满落幕
  7. 关于高考报志愿的一些规划建议
  8. 用C++ TR1 生成随机数
  9. Wps文档文件转换成pdf,支持doc-docx-ppt-pptx-xls
  10. Matlab多项式基本运算(1)( polyval和polyvalm的区别)
  11. oracle 数值加减乘除
  12. skd怎么接入_网易七鱼怎么接入? 网易七鱼三种接入方式介绍
  13. vue中改变v-html元素样式
  14. 计算机视觉入门(包含论文学习网址)
  15. 低调,中国的FPGA到底有多强?
  16. javascript的基本数据类型有哪些?
  17. stata统计分析及行业应用案例分析_描述性统计分析的应用——基于描述性统计分析识别优质股票...
  18. echart雷达图详细配置
  19. === 和 == 的区别
  20. Python数据分析案例:对全国大学综合数据分析,本可视化展示(附加2021全国大学排名爬虫源码)

热门文章

  1. 数据库索引原理讲解之二
  2. Arduino与Proteus仿真实例-WS2812实现音乐氛围灯仿真
  3. C语言药品信息管理系统
  4. 用js识别是否360浏览器
  5. 360被腾讯“抢”走刷机精灵,尴尬但不吃亏
  6. SLC MLC 和TLC
  7. FPGA工程师自述:实践中获得经验 多动手才是王道
  8. 看美国的教师怎么布置作业
  9. html为什么不能居中,我怎么不能居中这个html?
  10. 计算机音乐数字乐谱大全追光者,追光者歌谱