c++动态绑定和动态绑定
为了支持c++的多态性,才用了动态绑定和静态绑定。理解他们的区别有助于更好的理解多态性,以及在编程的过程中避免犯错误。
需要理解四个名词:
1、对象的静态类型:对象在声明时采用的类型。是在编译期确定的。
2、对象的动态类型:目前所指对象的类型。是在运行期决定的。对象的动态类型可以更改,但是静态类型无法更改。
关于对象的静态类型和动态类型,看一个示例:
- class B
- {
- }
- class C : public B
- {
- }
- class D : public B
- {
- }
- D* pD = new D();//pD的静态类型是它声明的类型D*,动态类型也是D*
- B* pB = pD;//pB的静态类型是它声明的类型B*,动态类型是pB所指向的对象pD的类型D*
- C* pC = new C();
- pB = pC;//pB的动态类型是可以更改的,现在它的动态类型是C*
3、静态绑定:绑定的是对象的静态类型,某特性(比如函数)依赖于对象的静态类型,发生在编译期。
4、动态绑定:绑定的是对象的动态类型,某特性(比如函数)依赖于对象的动态类型,发生在运行期。
- class B
- {
- void DoSomething();
- virtual void vfun();
- }
- class C : public B
- {
- void DoSomething();//首先说明一下,这个子类重新定义了父类的no-virtual函数,这是一个不好的设计,会导致名称遮掩;这里只是为了说明动态绑定和静态绑定才这样使用。
- virtual void vfun();
- }
- class D : public B
- {
- void DoSomething();
- virtual void vfun();
- }
- D* pD = new D();
- B* pB = pD;
让我们看一下,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()。
至于那些事动态绑定,那些事静态绑定,有篇文章总结的非常好:
我总结了一句话:只有虚函数才使用的是动态绑定,其他的全部是静态绑定。目前我还没有发现不适用这句话的,如果有错误,希望你可以指出来。
特别需要注意的地方
当缺省参数和虚函数一起出现的时候情况有点复杂,极易出错。我们知道,虚函数是动态绑定的,但是为了执行效率,缺省参数是静态绑定的。
- class B
- {
- virtual void vfun(int i = 10);
- }
- class D : public B
- {
- virtual void vfun(int i = 20);
- }
- D* pD = new D();
- B* pB = pD;
- pD->vfun();
- pB->vfun();
有上面的分析可知pD->vfun()和pB->vfun()调用都是函数D::vfun(),但是他们的缺省参数是多少?
分析一下,缺省参数是静态绑定的,pD->vfun()时,pD的静态类型是D*,所以它的缺省参数应该是20;同理,pB->vfun()的缺省参数应该是10。编写代码验证了一下,正确。
对于这个特性,估计没有人会喜欢。所以,永远记住:
“绝不重新定义继承而来的缺省参数(Never redefine function’s inherited default parameters value.)”
原创作品链接:
点击打开链接
转载于:https://www.cnblogs.com/shuaigezhaoguang/p/5847246.html
c++动态绑定和动态绑定相关推荐
- C++中的两种绑定方式(静态绑定、动态绑定)
两种绑定方式 静态绑定:在编译时刻,根据指针或引用变量的静态类型来决定成员函数属于哪一个类. 动态绑定:在运行时刻,根据指针或引用变量实际指向或引用的对象类型(动态类型)来确定成员函数属于哪一个类. ...
- uni-app动态绑定class和style
目录 动态绑定calss 动态绑定style 动态绑定calss class="[{'类名':条件},{'类名':条件},{'类名':条件}]" 为不同条件的image绑定不同的样 ...
- java中的动态绑定与静态绑定
首先是方法的参数是父类对象,传入子类对象是否可行 然后引出Parent p = new Children(); 这句代码不是很理解,google的过程中引出向上转型 要理解向上转型又引出了动态绑定 从 ...
- Java——动态绑定和多态
动态绑定是在执行期间(而不是编译期间)判断所用对象的实际类型,根据其实际的类型调用其相应的方法(确定选择哪个多态形式被调用). 首先是方法的参数是父类对象,传入子类对象是否可行 然后引出Parent ...
- java 静态绑定_java的动态绑定和静态绑定
首先是方法的参数是父类对象,传入子类对象是否可行 然后引出Parent p = new Children(); 这句代码不是很理解,google的过程中引出向上转型 要理解向上转型又引出了动态绑定 从 ...
- Vue教程(八)v-bind指令动态绑定
Vue教程(八)v-bind指令动态绑定 v-bind动态绑定 <!DOCTYPE html> <html lang="en"> <head>& ...
- vue动态获取css样式,Vue 框架之动态绑定 css 样式实例分析
今天的小实例是关于 Vue 框架动态绑定 css 样式,这也是非常常用的一个部分 首先说一下 动态绑定,相对的大家都知道静态绑定,静态绑定的话,直接加 class=""就可以了,使 ...
- js循环动态绑定带参数函数遇到的问题及解决方案[转]
今天写原生javascript时,想利用绑定事件实现类似jquery中on方法的功能:于是有了for循环里绑定事件,无意中发现定义类能解决好多问题! 例如:一个不确定长度的列表,在鼠标经过某一条的时候 ...
- 【Ant Design Pro 三】样式动态绑定 react样式绑定
第一步,创建样式文件,在页面目录下根据自己习惯创建一个less文件,用来写样式类 第二部,引用该文件 import styles from './details.less'; //details.le ...
最新文章
- 张亚勤清华AIR战队首次亮相,这阵容不是一般强
- PPT 下载 | 神策数据张涛:企业服务客户全生命周期运营三步曲客情诊断 解决方案库...
- QT学习:模型/视图基本概念
- [JavaScript] FireBug 调试
- mes实施顾问前景如何_国匠智能制造培训|MES的两种实施顾问类型
- 好程序员技术文档HTML5开发中的javascript闭包
- Ubuntu14.04配置python接口,测试的小问题
- ModelArts的雪中送炭,让我拿下CCF BDCI华为Severless工作负载预测亚军
- python的合法名称_python 命名规范
- Python Day10 MySQL 01
- Win11如何设置滚动条 Win11滚动条设置教程
- ANGULARJS 动态编译添加到dom中
- tomcat 7配置ssl教程
- 蠕虫病毒代码(纯属参考,请勿用于非法事件)
- 主成分分析结果成分不显著_spss主成分分析结果解读
- 电压跟随器的特点、作用和应用举例
- 《3D Point Cloud Registration for Localization using a Deep Neural Network Auto-Encoder》翻译
- Spark视频王家林大神第8课:彻底理解大数据机器学习
- Think twice, code once.
- 微信windows版本体验报告
热门文章
- 【网址收藏】安装VMware Tools显示灰色正确解决办法
- 分布式锁的三种实现的对比
- 请简要说明一下CyclicBarrier和CountDownLatch的区别?
- 一个栈输入序列为1,2,3,4,5,则下列序列中不可能是栈的输出序列是?
- RabbitMQ消息轮询重发消息(消息补偿)
- 【软考-软件设计师】计算机存储系统
- python memory usage_Python Pandas Index.memory_usage()用法及代码示例
- 基于 abp vNext 和 .NET Core 开发博客项目 - Blazor 实战系列(三)
- 自定义控件——旋转菜单
- 【代码示例】 一个简单的Java死锁