`
kuwoleft
  • 浏览: 1068302 次
文章分类
社区版块
存档分类
最新评论

深入理解C++的动态绑定和静态绑定

 
阅读更多

为了支持c++的多态性,才用了动态绑定和静态绑定。理解他们的区别有助于更好的理解多态性,以及在编程的过程中避免犯错误。
需要理解四个名词:
1、对象的静态类型:对象在声明时采用的类型。是在编译期确定的。
2、对象的动态类型:目前所指对象的类型。是在运行期决定的。对象的动态类型可以更改,但是静态类型无法更改。
关于对象的静态类型和动态类型,看一个示例:

3、静态绑定:绑定的是对象的静态类型,某特性(比如函数)依赖于对象的静态类型,发生在编译期。
4、动态绑定:绑定的是对象的动态类型,某特性(比如函数)依赖于对象的动态类型,发生在运行期。

让我们看一下,pD->DoSomething()和pB->DoSomething()调用的是同一个函数吗?
不是的,虽然pD和pB都指向同一个对象。因为函数DoSomething是一个no-virtual函数,它是静态绑定的,也就是编译器会在编译期根据对象的静态类型来选择函数。pD的静态类型是D*,那么编译器在处理pD->DoSomething()的时候会将它指向D::DoSomething()。同理,pB的静态类型是B*,那pB->DoSomething()调用的就是B::DoSomething()。

让我们再来看一下,pD->vfun()和pB->vfun()调用的是同一个函数吗?
是的。因为vfun是一个虚函数,它动态绑定的,也就是说它绑定的是对象的动态类型,pB和pD虽然静态类型不同,但是他们同时指向一个对象,他们的动态类型是相同的,都是D*,所以,他们的调用的是同一个函数:D::vfun()。

上面都是针对对象指针的情况,对于引用(reference)的情况同样适用。

指针和引用的动态类型和静态类型可能会不一致,但是对象的动态类型和静态类型是一致的。
D D;
D.DoSomething()和D.vfun()永远调用的都是D::DoSomething()和D::vfun()。

至于那些事动态绑定,那些事静态绑定,有篇文章总结的非常好:
我总结了一句话:只有虚函数才使用的是动态绑定,其他的全部是静态绑定。目前我还没有发现不适用这句话的,如果有错误,希望你可以指出来。

特别需要注意的地方
当缺省参数和虚函数一起出现的时候情况有点复杂,极易出错。我们知道,虚函数是动态绑定的,但是为了执行效率,缺省参数是静态绑定的。

有上面的分析可知pD->vfun()和pB->vfun()调用都是函数D::vfun(),但是他们的缺省参数是多少?
分析一下,缺省参数是静态绑定的,pD->vfun()时,pD的静态类型是D*,所以它的缺省参数应该是20;同理,pB->vfun()的缺省参数应该是10。编写代码验证了一下,正确。
对于这个特性,估计没有人会喜欢。所以,永远记住:
“绝不重新定义继承而来的缺省参数(Never redefine function’s inherited default parameters value.)”

关于c++语言
目前我基本上都是在c++的子集“面向对象编程”下工作,对于更复杂的知识了解的还不是很多。即便如此,到目前为止编程时需要注意的东西已经很多,而且后面可能还会继续增多,这也许是很多人反对c++的原因。
c++是Google的四大官方语言之一。但是Google近几年确推出了go语言,而且定位是和c/c++相似。考虑这种情况,我认为可能是Google的程序员们深感c++的复杂,所以想开发一种c++的替代语言。有时间要了解一下go语言,看它在类似c++的问题上时如何取舍的。

分享到:
评论

相关推荐

    深入理解C++的动态绑定与静态绑定的应用详解

    为了支持c++的多态性,才用了动态绑定和静态绑定。理解他们的区别有助于更好的理解多态性,以及在编程的过程中避免犯错误。需要理解四个名词:1、对象的静态类型:对象在声明时采用的类型。是在编译期确定的。2、...

    吕鑫:【C++语法与数据结构第22天】【第3堂课】动态绑定与静态绑定(面试题)

    1、讲解和演示动态绑定与静态绑定的概念与原理; 2、讲解和演示虚析构函数的概念与原理,并讲解为什么构造函数不能使用虚函数的原因;

    C++中的静态绑定和动态绑定

    C++在面向对象编程中,存在着静态绑定和动态绑定的定义,本节即是主要讲述这两点区分。  我是在一个类的继承体系中分析的,因此下面所说的对象一般是指一个类的实例。  首先我们需要明确几个名词定义:  静态...

    如何理解C++中的动态绑定

     我对于C++动态绑定的理解,一句话,是编译器用静态分析的方法加上虚拟函数的设计实现在程序运行时动态  智能执行正确虚拟函数的技术。因此要彻底理解动态绑定技术,只需要掌握两点,一是编译器的静态编译过程,...

    C++实现动态绑定代码分享

    对于C++动态绑定的理解,就是编译器用静态分析的方法加上虚拟函数的设计实现在程序运行时动态智能执行正确虚拟函数的技术。要彻底理解动态绑定,只需要掌握两点,一是编译器的静态编译过程,二是虚拟函数的基本知识...

    解析C++中的虚拟函数及其静态类型和动态类型

    虚拟函数是C++语言引入的一个很重要的特性,它提供了“动态绑定”机制,正是这一机制使得继承的语义变得相对明晰。 (1)基类抽象了通用的数据及操作,就数据而言,如果该数据成员在各派生类中都需要用到,那么就...

    C++ CLI In Action(1)

    什么是 C++/CLI 个人感觉将其看作是位于静态程序设计和动态程序设计之间的一座桥梁。...据此,对于“什么是 C++/CLI ”这一问题可能的一种答案便是“它是对静态 C++ 对象模型和动态 CLI 组件模型的一种绑定”。

    C++ CLI In Acton

    什么是 C++/CLI 个人感觉将其看作是位于静态程序设计和动态程序设计之间的一座桥梁。...据此,对于“什么是 C++/CLI ”这一问题可能的一种答案便是“它是对静态 C++ 对象模型和动态 CLI 组件模型的一种绑定”。

    C++的静态联编和动态联编详解

    静态联编是指在编译阶段就将函数实现和函数调用关联起来,因此静态联编也叫早绑定,在编译阶段就必须了解所有的函数或模块执行所需要检测的信息,它对函数的选择是基于指向对象的指针(或者引用)的类型,C语言中,...

    深入理解c++中virtual关键字

    c++中的函数调用默认不适用动态绑定。要触发动态绑定,必须满足两个条件:第一,指定为虚函数;第二,通过基类类型的引用或指针调用。由此可见,virtual主要主要是实现动态绑定。 2.那些情况下可以使用virtual关键字...

    C++中的静态多态和动态多态

    的C++已经是个多重泛型编程语言(multiparadigm programming lauguage),一个同时支持过程形式(procedural)... C++支持多种形式的多态,从表现的形式来看,有虚函数、模板、重载等,从绑定时间来看,可以分成静态多态和

    用ARP实现IP与MAC地址的绑定

    vc用ARP实现IP与MAC地址的绑定

    详解C++ 多态的两种形式(静态、动态)

    静态多态和动态多态的区别其实只是在什么时候将函数实现和函数调用关联起来,是在编译时期还是运行时期,即函数地址是早绑定还是晚绑定的。静态多态是指在编译期间就可以确定函数的调用地址,并生产代码,这就是静态...

    C_C++问题总结

    C/C++问题总结 1. 关键字 1.1 const 1.1.1 常量 1.1.2 修饰指针 ...3.18 动态绑定和静态绑定 3.19 实现不能在堆、栈分配的类,不能被继承的类 3.20 堆和栈 3.20.1 程序内存分配 3.20.2 堆和栈 3.20.3 栈溢出

    C++对象模型总结

    C++对象模型 第1章 关于对象 第2章 构造函数语意学 第3章 Data语意学 第4章 Function语意学 第5章 构造、析构、拷贝语意学 ...8.5.2 静态绑定与动态绑定 8.5.3 函数成员访问 8.5.4 多态的实现 8.5.5 虚析构函数

    详解C++虚函数的工作原理

    讨论静态绑定与动态绑定,首先需要理解的是绑定,何为绑定?函数调用与函数本身的关联,以及成员访问与变量内存地址间的关系,称为绑定。 理解了绑定后再理解静态与动态。 静态绑定:指在程序编译过程中,把函数...

Global site tag (gtag.js) - Google Analytics