从面向对象到面向COM.ppt
《从面向对象到面向COM.ppt》由会员分享,可在线阅读,更多相关《从面向对象到面向COM.ppt(77页珍藏版)》请在三一办公上搜索。
1、从面向对象到面向COM,主讲 叶长青华东师大教育信息技术学系2006-3-1 丽娃河畔,本课的内容及目标,内容:面向对象的一般概念 从面向对象到面向COM COM组件技术目标:了解程序设计技术的发展动向 提升程序设计能力 开阔专业视野,课程参考书目,COM原理与应用COM本质论 COM技术内幕 Advanced CORBA Programming with C+,面向对象的基本概念,为节省每一个字节而努力的阶段例:用PASCAL语句写成的程序段 AI:=AI+AT;AT:=AI AT;AI:=AI AT;目的是什么?我们现在习惯的写法是什么?不关心“空间的浪费”,更关心程序的清晰框架结构阶段例
2、:用FORTRAN语言编写的程序段 DO 5 I=1,N DO 5 J=1,N5 V(I,J)=(I/J)*(J/I),程序设计的发展历程,IF(X.LT.Y)GOTO 30IF(Y.LT.Z)GOTO 50SMALL=ZGOTO 7030 IF(X.LT.Z)GOTO 60SMALL=ZGOTO 7050 SMALL=YGOTO 7060 SMALL=X70 CONTINUE,SMALL=XIF(Y.LT.SMALL)SMALL=YIF(Z.LT.SMALL)SMALL=Z,X,Y,Z,谁,最,小,注重“重用性”的问题。面向对象 注重“标准化元件”的阶段。面向组件?软件企业分工细化阶段,类是
3、具有相同属性特征事物的集合。计算机专业语境下,类是封装了状态(变量)和操作(对变量处理的过程和函数)的抽象数据类型。(对应于标准数据类型)对象是实例,它反映了具体的事物。鸟,是类的概念。麻雀是鸟类的一个实例。一只麻雀?,对象由类来定义 一个对象可以与多个具有继承关系的类相联系,即:A是一个类,B、C、D是在A的基础上扩展后的新类,E,F,G则是在C类的基础上发展而来,而对象x 是F类的一个实例。,有关术语,封装、继承与多态,封装、继承与多态,面向对象概念的三个关键词,封装是实现面向对象程序设计的第一步,封装就是将数据或函数等集合在一个个的单元中(我们称之为类)。C+对类和对象的描述:Class
4、 studentPublic:成员函数1;成员函数2;Private:成员变量1;成员变量2;Int x,y;Student z;,类名,例一:C+中类的定义与实现说明:包含成员变量,成员函数,类的定义,对象的定义。例二、例三:成员函数在类内、类外实现的情形例四:成员函数是私有函数时的存取特性与意义,封装的意义在于保护或者防止代码(数据)被我们无意中破坏。在面向对象程序设计中数据被看作是一个中心的元素并且和使用它的函数结合的很密切,从而保护它不被其它的函数意外的修改。,从程序语言角度来看,在一个对象中代码和(或)数据可以是这个对象私有的,不能被对象外的部分直接访问。因而对象提供了一种高级保护以
5、防止程序被无关部分错误修改或错误地使用了对象的私有部分。当从对象外部试图直接对受保护的内部数据进行修改时,将被程序拒绝,只有通过对象所提供的对外服务函数才能够对其内部数据进行必要的加工,从而保证了数据加工的合法性。从这一意义上讲,把这种代码和数据的联系称为“封装”。换句话说,封装是将对象封闭保护起来,是将内部细节隐蔽起来的能力。,实现的细节是“可变的部分”。如果“块”是单个类,那么可变的部分通常用 private:或 protected:关键字来封装。“稳定的部分”是接口。好的接口提供了一个以用户的词汇简化了的视图,并且被从外到里的设计。(此处的“用户”是指其它开发者,而不是购买完整应用的最终
6、用户)。设计一个清晰的接口并且将实现和接口分离,只不过是允许用户使用接口并强迫用户使用接口。,如何才能防止其它程序员查看我的类的私有部分而破坏封装?,讨论,只要其它程序员写的代码不依赖于他们的所见,那么即使它们看了你的类的 private:和/或 proteced:部分,也不会破坏封装。换句话说,封装不会阻止人认识类的内部。封装只是防止他们写出依赖类内部实现的代码。倘若他们写的代码依赖于接口而不是实现,就不会增加维护成本。,不必这么做封装是对于代码而言的,而不是对人。,封装是一种安全装置吗?,封装要防止的是错误,而不是,间谍,封装!=安全。,钱掉了!,成员函数、成员变量中的另类,例五:构造函数
7、例六:析构函数例七:何时使用构造函数例八:友元函数例九:静态变量2005-9-30,继承的概念及重要性 inheritance:是软件重用的一种形式,将相关的类组织起来,并分亨其间的共通数据和操作行为。,最具吸引力的特点:新类可以从现有的类库中继承。提倡建立与现有的类有许多共性的新类,添加基类的所没有的特点以及取代和改进从基类继承来的特点来实现软件的重用 单重继承形成树状层次结构,由基类和派生类构成了一种层次关系,继承的层次在系统的限制范围内是任意的。,2.基类 父类定义了所有子类共通的对外接口和私有实现内容,父类被称为基类 成员函数:基类的私有成员只能被基类的成员函数和友元访问,基类的受保护
8、成员只能被基类及派生类的成员函数和友元访问,3.派生类 新类继承预定义基类的数据成员和成员函数,而不必重新编写数据成员和成员函数,这种新类叫派生(derived)类,派生类永远不能直接访问基类的私有成员重定义函数:派生类中无需继承的功能及要扩充的基类功能可以重定义成员函数,但在派生类再调用基类的同名函数时要用到作用域运算符Employee:print(),派生类的构造函数和析构函数:由于派生类继承了基类的成员,所以在建立派生类的实例对象时,必须调用基类的构造函数来初始化派生类对象中的基类成员。可隐式的调用基类构造函数,也可在派生类的构造函数中通过给基类提供初始化值(成员初始化值列表)明确的调用
9、构造函数。构造函数调用顺序:先执行基类的构造函数-派生类构造函数析构函数调用顺序正好相反。派生类不继承基类的构造函数、析构函数和赋值运算符,但派生类的构造函数和赋值运算符能调用基类的构造函数和赋值运算符。,类指针:指向基类的指针,指向派生类的指针。两者关系 可以直接用基类指针引用基类对象 可以直接用派生类指针引用派生类对象 可以用基类指针引用一个派生类对象,但只能引用基类成员。用派生类指针引用基类对象,绝对不行。必须先强制转换为基类指针,例一:基类和派生类的构造函数说明:在继承关系中构造函数执行顺序。例二:指向类的指针说明:int*p;/指向整型的指针P。例三:对不同的类使用相同的指针说明:程
10、序从头到尾始终只用一个“万能”指针指引一切。例四:使用指针时基类和派生类名字的冲突说明:如果基类和派生类中有同名函数,会怎样呢?,多态,多态性是面向对象的核心,它的最主要的思想就是可以采用多种形式的能力,通过一个用户名字或者用户接口完成不同的实现。通常多态性被简单的描述为“一个接口,多个实现”。在C+里面具体的表现为通过基类指针访问派生类的函数和方法。,动态联编:联编就是将模块或者函数合并在一起生成可 执行代码的处理过程,同时对每个模块或者函数调用分配内存地址,并且对外部访问也分配正确的内存地址。按照联编所进行的阶段不同,可分为两种不同的联编方法:静态联编和动态联编。在编译阶段就将函数实现和函
11、数调用关联起来称之为静态联编,静态联编在编译阶段就必须了解所有的函数或模块执行所需要检测的信息,它对函数的选择是基于指向对象的指针(或者引用)的类型。反之在程序执行的时候才进行这种关联称之为动态联编,动态联编对成员函数的选择不是基于指针或者引用,而是基于对象类型,不同的对象类型将做出不同的编译结果。,换一种说法:如果使用基类指针访问派生类中的同名函数,希望执行的是派生类中的成员函数,怎样实现?,下面我们看一个静态联编的例子:#include class shape public:void draw()coutfun();程序的输出结果?,程序的输出结果我们希望是I am circle,造成这个
12、结果的原因是静态联编。解释:静态联编需要在编译时候就确定函数的实现,但事实上编译器在仅仅知道shape的地址时候无法获取正确的调用函数,它所知道的仅是shape:draw(),最终结果只能是draw操作束缚到shape类上。产生I am shape的结果就不足为奇了。,事实上却输出了“I am shape”,为了能够引起动态联编,我们只需要将需要动态联编的函数声明为虚函数即可。动态联编只对虚函数起作用。我们在通过基类而且只有通过基类访问派生类的时候,只要这个基类中直接的或者间接(从上层继承)的包含虚函数,动态联编将自动唤醒。下面我们将上面的程序稍微改一下。#include class shap
13、e public:virtual void draw()coutdraw();程序执行得到了正确的结果I am circle。,关键,动态联编过程:编译器在执行过程中遇到virtual关键字的时候,将自动安装动态联编需要的机制,首先为这些包含virtual函数的类(注意不是类的实例)-即使是祖先类包含虚函数而本身没有-建立一张虚拟函数表VTABLE。在这些虚拟函数表中,编译器将依次按照函数声明次序放置类的特定虚函数的地址。同时在每个带有虚函数的类中放置一个称之为vpointer的指针,简称vptr,这个指针指向这个类的VTABLE。关于虚拟函数表,有几点必须声明清楚:1.C+编译时候编译器会在
14、含有虚函数的类中加上一个指向虚拟函数表的指针vptr。2.从一个类别诞生的每一个对象,将获取该类别中的vptr指针,这个指针同样指向类的VTABLE。,因此类、对象、VTABLE的层次结构可以用下图表示。其中X类和Y类的对象的指针 都指向了X,Y的虚拟函数表,同时X,Y类自身也包含了指向虚拟函数的指针。,#include class shape public:virtual void draw()coutshape:draw()endl;virtual void area()coutshape:area()endl;void fun()draw();area();class circle:pu
15、blic shapepublic:void draw()coutcircle:draw()endl;virtual void adjust()coutcircle:adjust()endl;main()shape oneshape;oneshape.fun();circle circleshape;shape 10.9,基类执行自己的成员函数,基类指针指向派生类对象,纯虚函数和抽象类,1、基类中的纯虚函数声明如下:Virtual type function_name(参数)=0;这样定义意味着,谁继承了该函数所在的类,谁就要负责实现该函数。2、如果一个类的定义中只包含纯虚函数,那么这个类称为抽
16、象类。,例一:静态联编说明:静态联编时,函数的选择由指针决定例二:动态联编说明:例三:动态联编说明:程序对函数的选择例四:使用虚拟函数说明:有什么特别之处吗?例五:多态,从面向对象过度到面向COM,COM是什么?,COM不是什么?,使用组件的优点:应用程序的定制组件库分布式组件,对组件的需求:1、动态链接2、消息封装,COM是一种跨应用和语言共享二进制代码的方法。COM明确指出了二进制模块(DLLs和EXEs)必须被编译成与指定的结构匹配。这个标准也确切地规定了在内存中如何组织COM对象。COM定义的二进制标准还必须独立于任何编程语言(如C+中的命名修饰)。一旦满足了这些条件,就可以轻松地从任
17、何编程语言中存取这些模块。由编译器负责所产生的二进制代码与标准兼容。这样使后来的人就能更容易地使用这些二进制代码。,使用和处理COM对象每一种语言都有其自己处理对象的方式。例如,C+是在栈中创建对象,或者用new动态分配。因为COM必须独立于语言,所以COM库为自己提供对象管理例程。下面是对COM对象管理和C+对象管理所做的一个比较:创建一个新对象C+中,用new操作符,或者在栈中创建对象。COM中,调用COM库中的API。删除对象C+中,用delete操作符,或将栈对象踢出。COM中,所有的对象保持它们自己的引用计数。调用者必须通知对象什么时候用完这个对象。当引用计数为零时,COM对象将自己
18、从内存中释放。由此可见,对象处理的两个阶段:创建和销毁,缺一不可。当创建COM对象时要通知COM库使用哪一个接口。如果这个对象创建成功,COM库返回所请求接口的指针。然后通过这个指针调用方法,就像使用常规C+对象指针一样。,当你调用CoCreateInstance()时,它负责在注册表中查找COM服务器的位置,将服务器加载到内存,并创建你所请求的coclass实例。以下是一个调用的例子,创建一个CLSID_ShellLink对象的实例并请求指向这个对象IShellLink接口指针。HRESULT hr;IShellLink*pISL;hr=CoCreateInstance(CLSID_Shel
19、lLink,/coclass 的CLSID NULL,/不是用聚合 CLSCTX_INPROC_SERVER,/服务器类型 IID_IShellLink,/接口的IID(void*)/指向接口的指针 if(SUCCEEDED(hr)/用pISL调用方法 else/不能创建COM对象,hr 为出错代码,创建COM对象为了创建COM对象并从这个对象获得接口,必须调用COM库的API函数,CoCreateInstance()。其原型如下:HRESULT CoCreateInstance(REFCLSID rclsid,LPUNKNOWN pUnkOuter,DWORD dwClsContext,RE
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 面向 对象 COM
链接地址:https://www.31ppt.com/p-5763761.html