首页 / 软件开发 / 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();
};
这两个具体子类的实现代码在此就省略不表了,参考上篇文章。