类工厂

为了使代码的可维护性好 (换句话说就是代码不动)所以我们选择在dll中添加类工厂

因为不同的功能返回的this指针不同  所以就需要不同的类工厂

因为不同的类工厂又需要大量的switch   case 来做判断所以并没有解决根本的问题

 

所以我们需要添加一个列表,用来记录对应的类

首先对应一个结构体  使工厂和特定id对应


//
返回一个类工厂对象 HRESULT __stdcall MyGetClassObject(const GUID & clsid, const GUID & iid, void** ppObject) { static IMyClassFactory *pObject = NULL; if (pObject == NULL) { int count = sizeof(g_factorys) / sizeof(g_factorys[0]); int i; for (i = 0; i < count; i++) { if (memcmp(&clsid, g_factorys[i].clsid, sizeof(GUID)) == 0) { pObject = g_factorys[i].pfn(); break; } } if (i == count) return E_NOINTERFACE; } 最后通过 找到对应的类工厂来调 对应的类对象 HRESULT hr = pObject->QueryInterface(iid, ppObject); if (FAILED(hr) && CSuperStringFactory::m_RefCount == 0) { delete pObject; pObject = NULL; } return hr; }

上面这个函数需要考虑第一次失败 空指针无法释放的问题 和第一次成功第二次失败 释放前面的对象问题

 

 

 

这三个纯虚函数 让所有的继承都必须实现这三个函数的实现,又因为代码几乎相同,造成了大量的重复代码,极度影响了可读性

为了使代码可读性好,所有我们使用了类模板

在其父类和本身类中插一个类   使模板类继承父类  自己继承模板类  模板类则实现 这三个纯虚函数的代码就行了。

template<typename class_name, typename class_base>
class ImpIUnknown :public class_base
{
public:
  ImpIUnknown(const GUID& iid)
    :m_iid(iid)
  {
  }
  virtual HRESULT __stdcall  QueryInterface(const GUID& iid, void** ppv)
  {
    if (memcmp(&iid, &IID_IMyUnkown, sizeof(GUID)) == 0)
    {
      *ppv = (IMyUnkown*)this;
      AddRef();
    }
    else if (memcmp(&iid, &m_iid, sizeof(GUID)) == 0)
    {
      *ppv = (class_name*)this;
      AddRef();
    }
    else
      return E_NOINTERFACE;
    return S_OK;
  }
  virtual HRESULT __stdcall  AddRef()
  {
    m_RefCount++;
    return S_OK;
  }
  virtual HRESULT __stdcall  Release()
  {
    if (--m_RefCount == 0)
      delete this;
    return S_OK;
  }
public:
  static int m_RefCount;
  const GUID& m_iid;
};

 

posted @ 2020-09-02 16:50  特权E5  阅读(206)  评论(0)    收藏  举报