
编译原理 面向对象语言的编译12.ppt
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
因为类时因为类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引用引用习习 题题。












