class IExtensibleObject
{
virtual void *Dynamic_cast(const char *pszType) = 0;
virtual void DuplicatePointer(void) = 0;
virtual void DestroyPointer(void) = 0;
};
基类接口抽象成这样的形式,Dynamic_cast()进行运行时类型识别,DuplicatePointer()实现引用计数,DestroyPointer()释放对象。
所解决的问题:
1、C++的dynamic_cast是编译器相关的,因此,从每一个接口显示地暴露一个广为人知的方法,由这个方法完成与dynamic_cast语义等价的功能。
2、多个指针指向同一个对象时,容易导致多次调用Delete()函数。因此采用引用计数机制保证Delete()只会被调用一次。
显然的,这三个方法是每一个接口都需要的,因此抽象到一个基类中。
class IFastString : public IExtensibleObject
{
public:
virtual int Length(void) const = 0;
virtual int Find(const char *psz) const = 0;
};
结合前面三部分(前面三篇文章)完成这一步以后,就能把类做成可重用的二进制组件了。
整理思路:
第一步:以动态库形式发布类,从物理上把类与客户分离。
第二步:采用接口与实现分离的方式,使客户无需在意类的内存布局。
第三步:采用抽象基类作为定义接口的方法,以vptr和vtbl的形式构建二进制防火墙。
第四步:使用LoadLibrary和GetProcAddress在运行时动态的选择同一接口的不同实现。
第五步:使用与RTTI类似的结构,在运行时动态询问对象,确定对象是否实现了指定接口。
第六步:使用引用计数,保证单个对象被多个指针引用,而不会重复删除。
这就是COM模型。