C/C++面试题:如何理解COM对象和接口?
考点:COM(组件对象模型)对象和接口的理解
答案:
一个对象实现一个接口
,意思就是该对象使用代码实现了接口的每个方法并且为这些函数通向COM库提供了COM的二进制指针
。然后COM使这些函数运行在请求了一个指向该接口的任何客户端
。 COM在接口的定义和实现上有根本的差别。接口实际上是由一组定义了用法的相互联系的函数原型组成
,只是它不能够被实现。这些函数原型就相当于C++中含有纯虚拟函数的基类。
一个接口定义制定了接口的成员函数、调用方法、返回类型、它们的参数的类型和数量,以及这些函数要干什么。但是这里并没有与接口实现相关的东西。
接口的实现就是程序员在一个接口定义上提供的执行相关动作的代码。客户调用完全是决定于接口的定义。接口实现的一个实例,实际上就是一个指向一组方法的指针,即是指指向一个接口的函数表,该函数表引用了该接口所有方法的实现。每个接口,是一个固定的一组方法的集合,在运行时通过globally unique interface identifier (IID) 来定位。这里,IID是com支持的globally unique identifier (GUID)的特殊的实例。这样做就不会产生单一系统上相同名字、接口的多个版本的COM之间的冲突了。
一个COM接口与C++类是不一样的。一个COM接口不是一个对象,它只是简单地关联一组函数,是客户和程序之间通信的二进制标准。只要它提供了指向借口方法的指针,这个对象就可以用任何语言来实现。COM接口是强类型的——每个接口有它自己的借口标识符。另外不能够用老版本的接口标识符定义新的版本,接口的IID定义的接口合同是明确、唯一的。
继承在COM里并不意味着代码的重用。因为接口没有实现关联,接口继承并意味着代码继承。意思仅仅是,一个接口同一个合同关联,就像C++的纯虚拟基类的创建和修改一样,可以添加方法或者更进一步的加强方法的使用。在COM里没有选择性继承。如果一个接口由另一个接口继承的话,它就包含了另一个接口定义的所有的方法。
管理实现一个COM对象的IUnknown:ueryInterface方法有三个主要规则:
(1)对象必须要有一个标识符。
(2)一个对象实例的接口集合必须是静态的(static)。
(3)在对象中从任何一个其他的接口查询此接口都应该成功。
通过引用计数来管理对象的生命周期。
AddRef() //增加引用
Realase() //减少引用