编写可复用性更好的C++代码:Band对象和COMToys(8)
2006-07-21 11:45:57 来源:WEB开发网// 在InitInstance中
new CTBandObjFactory(MYGUID,
RUNTIME_CLASS(CMyComClass),
IDR_MAINFRAME);
当创建了新的CTFactory,COMToys将它添加到主清单列表中;MFC对COleObjectFactory也做同样的事情。换句话说,正像我在面几个部分中解释的那样,不必专门做些什么来让MFC或COMToys知道你的类工厂。只要创建就行了。也不必删除类工厂,CTModule会在ExitInstance中自动完成。如果宁愿用老式方法将类工厂创建成一个静态全局类,那也没问题——但必须在自己的类工厂构造函数中设置m_bAutoDel = FALSE。避开DECLARE/IMPLEMENT_OLECREATE的主要理由是这样做了以后,我就能按理想的方式派生自己的类工厂。在BandObj例子中,自己当然必须创建一个类工厂;如面几个部分所做的那样,依然要调用AddBandClass。 总之,为了处理对象的创建,所有要做的工作是从 CTFactory 和 COleObjectFactory 派生自己的类工厂并记住#include文件DllEntry.cpp。剩下的事情由COMToys来做。为了让COM对象自注册,自己得写一个用于注册的资源脚本(RGS文件),并将它作为与类工厂有相同ID的REGISTRY资源添加到.RC文件。RGS文件的具体细节请下载源代码。
美中不足
我刚开始实现COMToys的时候,碰到一个小障碍。如果两个COM接口的方法有相同的名字和签名怎么办?虽然这种情况很少发生,但它确实发生了。例如,IPersistStream 和IPersistFile都有IsDirty。如果像下面这样写的话:
DECLARE_IPersistFile();
DECLARE_IPersistStream();
最后会声明IsDirty两次。尽管可以用手工方式进行更正,但这个问题总是让人有些忐忑不安。用手工来做,你必须重新敲入很多IMPLEMENT_IPersistStream代码,这太令人讨厌。为了避免这种事情,我引入了一个函数级的宏。
// IPersistFile - 整个接口
IMPLEMENT_IPersistFile(CMyClass,CTPersistFile);
// IPersistStream - 每个单独的函数
// IMPLEMENT_IPersistStream_IsDirty();
IMPLEMENT_IPersistStream_Load(CMyClass,CTPersistStream);
IMPLEMENT_IPersistStream_Save(CMyClass,CTPersistStream);
IMPLEMENT_IPersistStream_GetSizeMax(CMyClass,CTPersistStream);
这里再次印证了多继承(Magic MI Ruler)的优点,只有一个IsDirty,它应用到两个接口:IPersistFile 和 IPersistStream。这不就是希望的结果吗?如果你确实要让两个接口有相同的函数,又有不同的实现,你完全可以用普通的C++语法来充分限定方法名字:CMyComClass::IPersistStream::IsDirty 和 CMyComClass::IPersistFile::IsDirty。但用这个函数级的宏,至少不用重新敲入——甚至是不用知道它的实现。函数级的宏还提供了为一个或多个接口方法重载标准实现的途径——尽管如此,我觉得最好还是通过派生自己的实现类——CTMyPersistStream或别的类来完成,(待续)
更多精彩
赞助商链接