八年级语文上册com课件_第1页
八年级语文上册com课件_第2页
八年级语文上册com课件_第3页
八年级语文上册com课件_第4页
八年级语文上册com课件_第5页
已阅读5页,还剩27页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

COM第一个COM对象例子(G:\File\内部交流\赵国光\com\Example\DropTarget)IDropTarget的定义

interface

IDropTarget:public

IUnknown{

public:virtualHRESULTSTDMETHODCALLTYPEDragEnter(/*[unique][in]*/ IDataObject__RPC_FAR*pDataObj,/*[in]*/ DWORDgrfKeyState,/*[in]*/ POINTLpt,/*[out][in]*/ DWORD__RPC_FAR*pdwEffect)=0;

virtualHRESULTSTDMETHODCALLTYPEDragOver(/*[in]*/ DWORDgrfKeyState,/*[in]*/ POINTLpt,/*[out][in]*/ DWORD__RPC_FAR*pdwEffect)=0;

virtualHRESULTSTDMETHODCALLTYPEDragLeave(void)=0;

virtualHRESULTSTDMETHODCALLTYPEDrop(/*[unique][in]*/ IDataObject__RPC_FAR*pDataObj,/*[in]*/ DWORDgrfKeyState,/*[in]*/ POINTLpt,/*[out][in]*/ DWORD__RPC_FAR*pdwEffect)=0;

};什么是COMComponent

ObjectModel(组件对象模型)微软提出的二进制上的组件标准,定义了对象(组件)之间进行通信的协议。COM是一个更好的C++C++库厂商的麻烦某一个c++库厂商开发生产了一个算法,可以在O(1)时间阶内完成字符串搜索。为了让客户能够简单的使用这个算法,库厂商创建了一个类:FastString示例:faststring.hfaststring.cpp软件分发传统上,库厂商分发C++库一直以源码的形式进行.问题:代码复制,多个应用使用相同的代码占用磁盘空间以及内存.代码更新,将源码重新分发,重新编译链接,失去了模块化的特征.示意图应用A应用C应用BFastString.objFastString.objFastString.obj动态链接库(dll)为了解决重复代码以及更新困难的问题,将FastString类封装为一个dll是一个马上想到的方法._declspec(dllexport)关键字.引入库(import

library)示意图应用A应用C应用BFastString.dllDll引入库C++的可移植性C++缺少二进制级别的标准编译器和链接器的兼容性名字的问题,链接时表达符号名字为了支持函数重载和操作符重载,不同的编译器/链接器会任意修改入口点的符号名字,称为名字改编(name

mangling)使用extern

“C”可以消除名字改编现象,但只对全局函数有效.使用模块定义文件(Module

DefinitionFileDEF).在运行时表达语言的不同特征编译器厂商对语言的特征有不同方式的实现,异常(Exception)是一个例子.封装性的问题假如已经解决了编译器和链接器的问题,建立二进制组件的下一个障碍则和封装有关.FastString的Length方法有问题,修改FastString类的定义.FastString

dll升级为2.0,解决Length的问题.FastString

Dll分版本改名策略.新应用(用修改后的FastString)旧应用FastString.dll(2.0)接口与实现的分离封装的基础在C++中,这个原则没有应用到二进制层,因为C++类即是接口也是实现.如何做到接口与实现的分离将接口与实现分立成两个实体,在c++中表现为两个类,接口类和实现类.接口类只对一定的数据类型进行描述.实现类对数据类型作具体的实现.接口类的定义faststringitf.hclass

FastString;class

__declspec(dllexport)FastStringInf{

private:

FastString*m_pObj;

public:FastStringInf(const

char*psz);~FastStringInf();

intLength()const;

intFind(const

char*psz)const;};《示例:G:\File\内部交流\赵国光\com\Example\faststringdll2》使用面向对象的特性编译器/链接器的问题依然没有解决。利用所有编译器/链接器的一致性。复合结构在运行时表现形式对不同编译器一致.所有编译器使用相同的堆栈规则传递参数.所有C++编译器实现相同的虚函数调用机制.也就是说对每个c++编译器来说,一个对象在内存中如何表示,以及在运行时怎样调用虚函数都必须一致以上三条假设所有编译器必须要遵从.使用抽象基类作为二进制接口vptr以及vtbladjustorthunk(win32),CFRONT(solaris)vptrv_fun1v_fun2v_fun3vtblIFastString/接口FastString的抽象基类class

IFastString{public:virtual

intLength()const=0;virtual

intFind(const

char*psz)const=0;};vptrLengthFindvtblIFastString内存结构FastString/实现class

FastString

public:IFastString{private:

const

intm_cch;

char*m_psz;public: FastString(const

char*psz); ~FastString(void);

intLength(void)const;

intFind(const

char*psz)const;};vptrLengthFindvtblFastString内存结构m_cchm_psz唯一的全局函数extern“C”IFastString*CreateFastStringObject(constchar*psz){

returnnewFastString(psz);}new方法在dll内部被调用。析构函数的问题考虑如下用法:IFastString

*fs=CreateFastStringObject(“helloweveryone”);if(fs){ intpos=fs->Find(“very”); deletefs;}问题:内存泄露。原因:IFastString的析构函数并不是虚函数。解决办法:显示的使用删除方法删除自身。示例:G:\File\内部交流\赵国光\com\Example\faststringdll3动态载入dll的好处减少应用程序初始化的工作。dll不存在也不会导致系统出现错误。在运行时动态选择不同的实现。(另外的意义是组件升级)功能升级扩展带来的问题接口的改变或增加都可能导致客户代码重新编译。class

IFastString

{public:virtual

int

Delete(void)

=

0;virtual

intLength()const=0;virtual

intFind(const

char*psz)const=0;//新功能virtualintFindN(constchar*psz)const=0;}新方法追加在接口定义的尾部,老客户使用新服务可以,反过来则会崩溃。实现类暴露多个接口接口从另一个接口继承实现类从多个接口继承运行时类型识别(RTTI),dynamic_cast<>.接口继承继承接口类定义:classIFastString2:publicIFastString{public:

virtual

intFindN(constchar*psz)const=0;}运行时类型识别用法:int

FindNth(IFastString*fs,intn){ IFastString2*fs2=dynamic_cast<IFastString2*>(fs);

if(fs2)j

returnfs2->FindN(“very”,n);

else{

error(“类型转换失败,不能进行查找”);//或者用别的实现

return-1; }}接口继承2

–永久性支持//永久性对象classIPersistObject{public:

virtualvoidDelete()=0;

virtual

boolLoad(constchar*filename)=0;

virtual

bool

Save(constchar*

filename)

=

0;}//支持永久性的FaststringclassFastString:publicIFastString,publicIPersistObject{private:

intm_cch;char*m_psz;public: FastString(const

char*psz); ~FastString(void);

voidDelete(void);

//IFastString的方法

intLength(void)const;

intFind(const

char*psz)const;

//IPersistObject的方法

bool

Load(const

char*filename);

boolSave(const

char*filename);}boolSaveString(IFastString*fs,char*filename){IPersistObject*po=

dynamic_cast<IPersistObject*>(fs);

if(po)

returnpo->Save(filename);

else

returnfalse;}RTTI的问题RTTI是与编译器相关的特性,不同的变异其厂商对其有着不同的实现。这样就破坏了以抽象基类作为接口而获得的编译器独立性。解决方法:每个接口自己实现dynamic_cast的功能,这样仍然保持编译器独立性。修改后的接口类classIPersistObject{public:

virtual

void*Dynamic_Cast(const

char*type)

=0;

virtual

voidDelete()=0;

virtual

boolLoad(constchar*filename)=0;

virtual

boolSave(constchar*filename)=0;}classIFastString{public:

virtualvoid*Dynamic_Cast(const

char*type)

=0;

virtualvoidDelete()=0;

virtualintLength()=0;

virtualintFind(constchar*psz)=0;}//extractmethodclassIBaseObject{public:virtualvoid*Dynamic_Cast(const

char*type)

=0;virtualvoidDelete()=0;}实现Dynamic_Cast方法classFastString:publicIFastString,publicIPersistObject{//…};void*FastString:Dynamic_Cast(constchar*type){

if(strcmp(type,”IFastString”)==0)

return

static_cast<IFastString*>this;

elseif(strcmp(type,”IPersistObject”)==0)

returnstatic_cast<IPersistObject*>this;

elseif(strcmp(type,”IBastObject”)==0)

returnstatic_cast<IFastString*>this; //????? returnNULL;}转为IFastString的原因:多继承引起的二义性。消除多继承引起的二义性可以使用虚基类技术,但c++里虚基类同样是编译器相关的特性。资源管理voidf(void){ IFastString*pfs=0; IPersistObject*ppo=0; pfs=CreateFastString(“Helloeverybody.");

if(pfs){ ppo=(IPersistObject*)pfs->Dynamic_Cast("IPersistObject");

if(!ppo) pfs->Delete();

else{ ppo->Save("C:\\test.txt"); ppo->Delete(); } }}问题创建的对象是IFastString指针接收的,但却是用IPersistObject接口Delete,并且对象只能被释放一次。在此,由于他们都是指向的同一个对象,所以资源释放没问题,但是如果在复杂的代码中,包含多个接口,多个对象的时候,资源释放将变得非常复杂和不易控制。解决方法:将资源释放部分放到实现内部,每个对象自己控制自己的生命周期。Delete方法的改造//基类抽象接口class

IBaseObject{

virtual

void*Dynamic_Cast(const

char*type); //virtual

void

Delete(void);

virtualvoidAddPointer();

virtualvoidDelPointer();};//实现实现类维护一个变量,在指针复制的时候增加,指针不用的时候减少,减至0时将对象销毁。class

FastString:publicIFastString,publicIPersistObject{

intm_pcount;public:

voidAddPointer(){ m_pcount++; }

voidDelPointer(){ if(--m_pcount==0) deletethis; }}接下来需要修改管理指针的接口,在指针被复制的时候调用AddPointer.对FastString

Dll来说,有两个地方需要修改,一是创建对象接口CreateFastStringObject,一是运行时动态类型转换接口Dynamic_Castvoid*FastString:Dynamic_Cast(constchar*type){ void*obj=NULL;

if(strcmp(type,”IFastString”)==0) obj=static_cast<IFastString*>this;

elseif(strcmp(type,”IP

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论