首页 / 软件开发 / VC.NET / COM组件开发实践(五)---From C++ to COM :Part 2
COM组件开发实践(五)---From C++ to COM :Part 22010-05-29 博客园 Phinecos(洞庭散人)一,使用抽象基类重用C++对象在上一篇文章《COM组件开发实践(四)---From C++ to COM :Part 1》中,我们已经将要复用的C++对象封装到DLL中了,对象的声明和实现已经实现了剥离,但还有问题:对象的私有成员(如我们示例中CDB类的数组变量m_arrTables)还是被客户看得一清二楚,即使客户没办法去访问它们;若对象改变了它的数据成员的大小,则所有的客户程序必须重新编译。而实际上,客户需要的仅仅是对象的成员函数的地址,因此使用抽象基类可以很好地满足以上需求,客户就不会包含对象的私有数据成员,就算对象改变了数据成员的大小,客户程序也不用重新编译。1.修改接口文件首先将接口都改成抽象基类,这是客户程序唯一所需要的代码。具体包括下面几步:1)将CDB和CDBSrvFactory的函数都改成纯虚函数。2)删除数据成员。3)删除所有成员函数的引出标志。4)将CDB改成IDB(表示DB的接口),CDBSrvFactory改成IDBSrvFactory(表示DB类工厂的接口)typedef long HRESULT; #define DEF_EXPORT __declspec(dllexport) class IDB { // Interfaces public: // Interface for data access virtual HRESULT Read(short nTable, short nRow, LPWSTR lpszData) =0; virtual HRESULT Write(short nTable, short nRow, LPCWSTR lpszData) =0; // Interface for database management virtual HRESULT Create(short &nTable, LPCWSTR lpszName) =0; virtual HRESULT Delete(short nTable) =0; // Interfase para obtenber informacion sobre la base de datos virtual HRESULT GetNumTables(short &nNumTables) =0; virtual HRESULT GetTableName(short nTable, LPWSTR lpszName) =0; virtual HRESULT GetNumRows(short nTable, short &nRows) =0; virtual ULONG Release() =0; }; class IDBSrvFactory { // Interface public: virtual HRESULT CreateDB(IDB** ppObject) =0; virtual ULONG Release() =0; };
HRESULT DEF_EXPORT DllGetClassFactoryObject(IDBSrvFactory ** ppObject);2.修改对象程序在DLL项目中,我们实现为这个抽象接口声明并实现具体的子类,让CDB从IDB派生,CDBSrvFactory从IDBSrvFactory派生,并且把类工厂CDBSrvFactory的CreateDB方法的参数由CDB**改成IDB**。#include "..interfacedbsrv.h" typedef long HRESULT; class CDB : public IDB { // Interfaces public: // Interface for data access HRESULT Read(short nTable, short nRow, LPWSTR lpszData); HRESULT Write(short nTable, short nRow, LPCWSTR lpszData); // Interface for database management HRESULT Create(short &nTable, LPCWSTR lpszName); HRESULT Delete(short nTable); // Interfase para obtenber informacion sobre la base de datos HRESULT GetNumTables(short &nNumTables); HRESULT GetTableName(short nTable, LPWSTR lpszName); HRESULT GetNumRows(short nTable, short &nRows); ULONG Release(); //CPPTOCOM: need to free an object in the DLL, since it was allocated here // Implementation private: CPtrArray m_arrTables; // Array of pointers to CStringArray (the "database") CStringArray m_arrNames; // Array of table names public: ~CDB(); }; class CDBSrvFactory : public IDBSrvFactory { // Interface public: HRESULT CreateDB(IDB** ppObject); ULONG Release(); };这两个具体子类的实现代码在此就省略不表了,参考上篇文章。