欢迎来到天天文库
浏览记录
ID:51496070
大小:207.00 KB
页数:20页
时间:2020-03-25
《北大编译原理chapter10.ppt》由会员上传分享,免费在线阅读,更多相关内容在行业资料-天天文库。
1、面向对象语言通过将数据和作用其上的操作封装成一种新的数据类型,实现了很好的数据抽象性通过继承和组合能够方便的实现模块的可重用性和可扩充性本章我们概述面向对象语言的重要概念和实现它们的方法序面向对象语言的概念对象类继承性-对象一个对象由它的状态和操作于该状态的过程组成,状态由一组属性的值表示,过程也叫做方法或行为。属性和方法共同形成了对象的特征。对象封装了数据及其上的操作,它是一个独立的有约束的实体,有自己的记忆和活动。-类用户可以将一些属性和方法封装在自定义的类型中,这种类型就称为类。一个类规范了类中对象的属性和
2、方法,一个对象要想属于一个类,它必须至少应该包含该类所具有的特征,当然还可以含有其它一些特征。-继承:从已有的类派生出新的类。子类继承父类的属性与操作,可对其修改;子类增加新的内容。目的:复用单继承、多继承类与类之间构成了层次关系。类类类类类类类类类多继承表示起来复杂,实现起来不容易,存在有语义模糊性问题,存在属性名和函数名冲突问题。不鼓励使用多继承,有的语言不支持。-多态多态是指基类的方法调用可以根据实际运行的对象类型不同实现对不同函数体的调用。考虑类间的层次关系,解决功能和行为的再抽象。单继承的编译方案子类中
3、属性的偏移值应该如何定?对于单继承,即每个派生类只有一个父类的情况,采用最简单的“前置”技术就能解决上面的问题。例如当B从A派生而来时,那些从A继承来的属性被置于B的属性域的最开始,并和它们在A中出现的顺序是相同的。那些从B派生的属性被放在后面,ClassA{inta;};ClassB:publicA{intb;intc;};ClassC:publicA{intd;};ClassD:publicB{inte;};AaBabcCadBabce属性的单继承单继承的编译方案方法的编译同普通函数的编译很相似:它被
4、编译变换成机器代码存于指令空间的一个特定地址中。在编译的语义分析阶段,每一个变量的环境域会包含一个指针指向它的类描述符;每个类描述符又包含一个指向它父类的指针和自身的方法实例列表;每个方法实例又包含一个对应的机器指令级的标号。§静态方法静态方法是指在编译时就可以确定下来执行函数体的方法。在c++中没有特殊标明的方法都属于此类。例如下面的c++程序:classA{intx;voidf();}classB:publicA{voidg();}classC:publicB{voidg();}classD:publicC{
5、inty;voidf();}该程序中所有的方法都是静态方法。当我们调用一个方法c.f()时,编译出的机器代码是依据变量c的类型来定的,而不是依据c所指向的对象类型来定的,这样静态方法对应的执行函数体就可以在编译时确定下来。为了编译类似于c.f()的方法调用,编译器首先要找到c所对应的类描述符,假设为C;接着要在C中查找方法f,假设没有找到;然后编译器再查找C的父类B,然后在B中寻找方法f,以此类推。假设最后在某个祖先类A中找到了静态方法f,这时编译器就可以将c.f()这个调用编译为机器标号A_f。§动态方法动态方
6、法是指在编译时无法确定下来执行函数体,要到运行时根据变量指向的实际类型来确定的方法。在c++中用带有virtual关键字的虚函数来表示。与静态方法相反,编译出的机器代码不是依据变量的类型来定而是依据变量所指向的对象类型来定的。对于前面的例子,类A中的方法f是一个动态方法,它在类C的子类D中被覆盖。这样当我们同样调用c.f()时,我们没有办法在编译时确定变量c指向的类型是D还是C,因而也就无法确定应该编译成机器标号D_f,还是A_f。动态方法表(也称为虚函数表)£为解决动态方法在编译时无法确定应该编译成的机
7、器标号,引入了动态方法表,该表记录了每个动态方法对应的机器标号。£当类B从类A派生出来以后,它的动态方法表首先包含A中已有的方法,然后才是自己新增的动态方法。classA{intx;voidf();}classB:publicA{voidg();}classC:publicB{voidg();}classD:publicC{inty;voidf();}AA_fBA_fB_fCA_fC_gBD_fC_g类的动态方法表当定义一个对象时,我们会在对象的起始地址处插入一个指针指向该对象所在类的动态方法表,这
8、个指针在c++中也被称为虚指针。有了这些准备,当编译c.f()时,就会生成以下的指令:1.在对象c的起始地址取得虚指针;2.从虚指针指向的动态方法表对应的f所在的偏移量处(这是一个常量)获得机器标号p;3.跳转到地址p处继续执行,并保存返回结果。根据上面属性和方法的编译方案,下面程序对应的对象实例如右图所示:classA{intx;voidf();}classB:pu
此文档下载收益归作者所有