资源预览内容
第1页 / 共33页
第2页 / 共33页
第3页 / 共33页
第4页 / 共33页
第5页 / 共33页
第6页 / 共33页
第7页 / 共33页
第8页 / 共33页
第9页 / 共33页
第10页 / 共33页
亲,该文档总共33页,到这儿已超出免费预览范围,如果喜欢就下载吧!
资源描述
第十二章第十二章 面向对象语言的编译面向对象语言的编译本章内容本章内容概述面向对象语言的重要概念和实现技术概述面向对象语言的重要概念和实现技术以以C+语言为例,介绍如何将语言为例,介绍如何将C+程序翻译成程序翻译成C程序程序实际的编译器大都把实际的编译器大都把C+程序直接翻译成低级程序直接翻译成低级语言程序语言程序12.1 面向对象语言的概念面向对象语言的概念12.1.1 对象和对象类对象和对象类对象对象由一组由一组属性属性和操作于这组属性的过程组成和操作于这组属性的过程组成属性到值的映射称为对象的属性到值的映射称为对象的状态状态 ,过程称为,过程称为方法方法对象类对象类一类对象的总称,一类对象的总称,规范了该类中对象的属性和方规范了该类中对象的属性和方法,包括它们的类型和原型法,包括它们的类型和原型对象有自己存放属性的存储单元;同一个类的对对象有自己存放属性的存储单元;同一个类的对象可以共享方法的代码象可以共享方法的代码对象类形成了面向对象语言的模块单元对象类形成了面向对象语言的模块单元下面将把术语下面将把术语“类类”和和“类型类型”看成是同义的看成是同义的12.1 面向对象语言的概念面向对象语言的概念12.1.2 继承继承图形对象的继承层次结构图形对象的继承层次结构GraphicalObj translate scale PolyLine translate scale lengthClosedGraphics area Ellipse translate scale areaPolyGon areaRectanglearea Triangle 12.1 面向对象语言的概念面向对象语言的概念继承继承基类、派生类、子类、抽象类基类、派生类、子类、抽象类子类型规则子类型规则当当某某个个类类型型的的一一个个对对象象在在某某个个输输入入位位置置被被需需要要或或作作为为函函数数的的返返回回值值时时,其其任任何何子子类类型型的的对对象象允允许许出出现现在这些地方在这些地方类类B的一个对象,若它不同时是的一个对象,若它不同时是B的某个真子的某个真子类的对象,那么称该对象是类的对象,那么称该对象是B的的真对象真对象,称,称B是该对象的是该对象的运行时类型运行时类型12.1 面向对象语言的概念面向对象语言的概念12.1.2 继承继承图形对象的继承层次结构图形对象的继承层次结构GraphicalObj translate scale PolyLine translate scale lengthClosedGraphics area Ellipse translate scale areaPolyGon areaRectanglearea Triangle B12.1 面向对象语言的概念面向对象语言的概念方法选择规则方法选择规则如果类如果类B继承类继承类A并且重写了方法并且重写了方法m,那么对那么对类类B的对象的对象b来说来说, 即使它作为类即使它作为类A的对象使用的对象使用, 也必须使用在类也必须使用在类B中定义的方法中定义的方法m12.1 面向对象语言的概念面向对象语言的概念12.1.2 继承继承图形对象的继承层次结构图形对象的继承层次结构GraphicalObj translate scale PolyLine translate scale lengthClosedGraphics area Ellipse translate scale areaPolyGon areaRectanglearea Triangle AB12.1 面向对象语言的概念面向对象语言的概念动态绑定规则动态绑定规则当对象当对象o的一个方法可能被子类重新定义时,的一个方法可能被子类重新定义时,如果编译器不能确定如果编译器不能确定o的运行时类型,那么必的运行时类型,那么必须对该方法进行动态绑定须对该方法进行动态绑定void zoom (GraphicalObj &obj, double zoom_factor, Point ¢er) obj.translate ( center.x, center.y); / 将将“中心中心”移至移至“点点(0, 0)”obj.scale (zoom_factor); / 缩放缩放12.1 面向对象语言的概念面向对象语言的概念12.1.3 信息封装信息封装大多数面向对象语言提供了一种机制,它可大多数面向对象语言提供了一种机制,它可用来将类的特征分成私有的和公共的用来将类的特征分成私有的和公共的某些面向对象语言用不同的上下文区分作用某些面向对象语言用不同的上下文区分作用域,如域,如“在一个类中在一个类中”、“在派生类中在派生类中”、“在友元类中在友元类中”等等等等由编译器来实现这些作用域规则是简单而又由编译器来实现这些作用域规则是简单而又明显明显的的 12.2 方法的编译方法的编译 先定义一般的图形对象类先定义一般的图形对象类GraphicalObj如下如下:class GraphicalObj virtual void translate (double x_offset, double y_offset);virtual void scale (double factor);. . . / 可能还有一些其它方法可能还有一些其它方法; 12.2 方法的编译方法的编译 class Point : public GraphicalObj double xc, yc; public : void translate (double x_offset, double y_offset) xc += x_offset; yc += y_offset; void scale (double factor) xc * *= factor; yc * *= factor;Point(double x0 = 0, double y0 = 0) xc = x0; yc = y0; void set(double x0, double y0) xc = x0; yc = y0;double x(void) return xc;double y(void) return yc;double dist (Point &);12.2 方法的编译方法的编译 将一个将一个C+语言的类翻译成语言的类翻译成C语言的程序段,主语言的程序段,主要工作有如下几点要工作有如下几点( (由继承引出的问题暂不考虑由继承引出的问题暂不考虑) )将将C+语言中一个类的所有非静态属性构成一语言中一个类的所有非静态属性构成一个个C语言的结构类型,取类的名字作为结构类语言的结构类型,取类的名字作为结构类型的名字型的名字类的静态属性是该类的所有对象所共有的类的静态属性是该类的所有对象所共有的, ,应当应当翻译成翻译成C中的全局变量,但是需要改一个名字中的全局变量,但是需要改一个名字C+语言中类的对象声明不加翻译就成了语言中类的对象声明不加翻译就成了C语言语言中相应结构类型的变量声明中相应结构类型的变量声明12.2 方法的编译方法的编译 将将C+语言中类的非静态方法翻译成语言中类的非静态方法翻译成C语言的函语言的函数,对应的方法和函数的区别有下面几点:数,对应的方法和函数的区别有下面几点:函数的名字必须在原来方法名的基础上修改函数的名字必须在原来方法名的基础上修改函数声明增加一个形参函数声明增加一个形参this在函数体中出现的函数调用也要增加一个实参在函数体中出现的函数调用也要增加一个实参在方法中对本对象的非静态属性的访问,改成对在方法中对本对象的非静态属性的访问,改成对this相应域的访问。在方法中对其它对象的非静态相应域的访问。在方法中对其它对象的非静态属性的访问不必修改属性的访问不必修改类的静态方法在定义和调用的地方都需要改名类的静态方法在定义和调用的地方都需要改名12.2 方法的编译方法的编译 方方 法法 函函 数数 原型原型 返回类型返回类型 m(形参表形参表) ) 返回类型返回类型 fm( (C &this, , 形参表形参表) )调用调用 m(实参表)实参表)o.n(实参表)实参表)fm(this,实参表)实参表) fn(o,实参表)实参表) 属性访问属性访问 ko.kthis.ko.k类类C的方法的方法m被翻译成函数被翻译成函数fm 12.2 方法的编译方法的编译 类类Point的方法的方法translate翻译成函数翻译成函数translate_ _5Pointddvoid translate_ _5Pointdd(Point this, double x_offset , double y_offset) this.xc += x_offset; this.yc += y _offset;12.3 继承的编译方案继承的编译方案如果类如果类B直接或间接继承类直接或间接继承类A,类类B的对象可以的对象可以用在几乎所有类用在几乎所有类A的对象可用的地方的对象可用的地方为了使类为了使类B的对象可以作为类的对象可以作为类A的对象使用,编的对象使用,编译器必须能以一种有效的方式产生类译器必须能以一种有效的方式产生类B的对象的对象的的A视图视图由于类由于类A的虚方法可以在类的虚方法可以在类B中被重写,又需要中被重写,又需要B视图能够有效地从视图能够有效地从A视图产生视图产生这样,编译器要求类的对象具有某种灵活的结这样,编译器要求类的对象具有某种灵活的结构构12.3 继承的编译方案继承的编译方案图形对象的继承层次结构图形对象的继承层次结构GraphicalObj translate scale PolyLine translate scale lengthClosedGraphics area Ellipse translate scale areaPolyGon areaRectanglearea Triangle 12.3 继承的编译方案继承的编译方案#include “graphicalobj.h”#include “list.h” #include “point.h”class PolyLine : public GraphicalObj list points; public:void translate (double x_offset, double y_offset);virtual void scale (double factor);virtual double length (void);#include “polyline.h”class Rectangle : public PolyLine double side1_length, double side2_length; public :Rectangle (double s1_len, double s2_len, double x_angle = 0);void scale (double factor);double length (void);12.3.1 单一继承的编译方案单一继承的编译方案12.3 继承的编译方案继承的编译方案void zoom (GraphicalObj &obj, double zoom_factor, Point ¢er) obj.translate ( center.x, center.y); / 将将“中心中心”移至移至“点点(0, 0)”obj.scale (zoom_factor); / 缩放缩放如果函数如果函数zoom作用于矩形,那么作用于矩形,那么zoom的体必须的体必须调用调用Rectangle的缩放函数,而不是的缩放函数,而不是PolyLine甚至甚至GraphicalObj的缩放函数的缩放函数 12.3 继承的编译方案继承的编译方案必须解释编译器是怎样有效地实现动态绑定的必须解释编译器是怎样有效地实现动态绑定的编译器为每个类建立一个方法表,它们包含一编译器为每个类建立一个方法表,它们包含一个类或它的超类中所有定义为个类或它的超类中所有定义为virtual的方法的的方法的入口入口每个对象在每个对象在C程序中有对应的结构,现在为这程序中有对应的结构,现在为这样的结构增加一个域,该域是方法表的指针样的结构增加一个域,该域是方法表的指针继承类方法表的产生:首先拷贝基类的方法表继承类方法表的产生:首先拷贝基类的方法表, ,被重新定义的方法由新的定义覆盖;然后,新被重新定义的方法由新的定义覆盖;然后,新引入的方法被追加到这张表上引入的方法被追加到这张表上12.3 继承的编译方案继承的编译方案图形对象的不同子类的方法表图形对象的不同子类的方法表GraphicalObjPolyLineRectangle length_RA scale_RA translate_PL length_PL scale_PL translate_PL scale_GO translate_GO12.3 继承的编译方案继承的编译方案Rectangle的对象表示的对象表示 length_RA scale_RA translate_PL side2_length side1_length points 视图:视图: GraphicalObj PolyLine RectangleRectangle 方法表方法表12.3 继承的编译方案继承的编译方案12.3.2 重复继承的编译方案重复继承的编译方案重重复复继继承承对对语语言言定定义义和和编编译译器器设设计计来来说说,都都具具有很大的挑战性有很大的挑战性B1和和B2间的冲突与矛盾间的冲突与矛盾重复继承重复继承可以有多个实例可以有多个实例只能有一个实例只能有一个实例AB1B2C12.3 继承的编译方案继承的编译方案B1和和B2间的冲突与矛盾间的冲突与矛盾这是这是语言定义问题语言定义问题,解决办法:,解决办法:将将B1定义为主要后代,冲突解决优先于定义为主要后代,冲突解决优先于B1语言允许重新命名被继承的特征语言允许重新命名被继承的特征语言提供显式地手段来解决冲突语言提供显式地手段来解决冲突B1:n或或B2:n 实现起来并无什么困难,实现起来并无什么困难,只涉及到编译器符号表的只涉及到编译器符号表的组织和管理问题组织和管理问题AB1B2C12.3 继承的编译方案继承的编译方案重复继承的多个实例重复继承的多个实例附加(附加(B1)AA附加(附加(B2)附加(附加(C)附加(附加(B1)A附加(附加(B2)附加(附加(C)重复继承的单个实例重复继承的单个实例下面两种方式都有应用,仅讨论前者下面两种方式都有应用,仅讨论前者12.3 继承的编译方案继承的编译方案独立的重复继承的编译方案独立的重复继承的编译方案继承类继承类C的对象包含基类的对象包含基类B1和和B2的完整拷贝的完整拷贝 来自基类的继承是相互独来自基类的继承是相互独立的立的B1B2附加(附加(C)独立的重复继承时的独立的重复继承时的对象结构(程序视图)对象结构(程序视图)12.3 继承的编译方案继承的编译方案重复继承在下述情况导致冲突和二义重复继承在下述情况导致冲突和二义当多实例的特征被用于访问、当多实例的特征被用于访问、调用和覆盖的时候调用和覆盖的时候当类当类C的对象的的对象的A视图被建立视图被建立时。因为类时。因为类C的对象包含多个的对象包含多个类类A子对象子对象可见性规则可以在某些情可见性规则可以在某些情况下帮助避免这些困难况下帮助避免这些困难 B1B2附加(附加(C)独立的重复继承时的独立的重复继承时的对象结构(程序视图)对象结构(程序视图)12.3 继承的编译方案继承的编译方案独立的重复继承的对象结构(实现视图)独立的重复继承的对象结构(实现视图)(把单一继承的编译方案加以扩充把单一继承的编译方案加以扩充 )B1B2附加附加(C)C方法方法B2方法方法B1方法方法B2方法方法C方法表方法表C:B2方法表方法表C引用,引用,B1引用引用B2引用引用12.3 继承的编译方案继承的编译方案C对象的对象的B1视图是视图是C视图的开头部分视图的开头部分C视图的开头部分不能作为视图的开头部分不能作为B2视图视图B1B2附加附加(C)C方法方法B2方法方法B1方法方法B2方法方法C方法表方法表C:B2方法表方法表C引用,引用,B1引用引用B2引用引用12.3 继承的编译方案继承的编译方案困难的事情是,从困难的事情是,从B2的视图来恢复的视图来恢复C的视图的视图B1B2附加附加(C)C方法方法B2方法方法B1方法方法B2方法方法C方法表方法表C:B2方法表方法表C引用,引用,B1引用引用B2引用引用12.3 继承的编译方案继承的编译方案编译器把用于确定所需视图的偏移存放在方法表编译器把用于确定所需视图的偏移存放在方法表中下邻该方法指针的地方中下邻该方法指针的地方B1B2附加附加(C)C方法方法B2方法方法B1方法方法B2方法方法C方法表方法表C:B2方法表方法表C引用,引用,B1引用引用B2引用引用12.3 继承的编译方案继承的编译方案独立的重复继承的对象结构(实际视图)独立的重复继承的对象结构(实际视图)B1B2附加附加(C)C方法方法B1方法方法B2方法方法C方法表方法表C引用,引用,B1引用引用B2引用引用习习 题题
收藏 下载该资源
网站客服QQ:2055934822
金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号