Шаг 23 - Классы и интерфейсы

Итак, настало время разобраться, как должны быть организованы классы для реализации интерфейсов типа IUnknown и IClassFactory. Вот. Первое, мы должны завести класс наследуемый интерфейс IUnkonwn. Вот например так.

class  IMath  :  public  IUnknown
{
public:
    STDMETHOD(Add)      (  long,  long,  long*  )  PURE;
    STDMETHOD(Subtract) (  long,  long,  long*  )  PURE;
    STDMETHOD(Multiply) (  long,  long,  long*  )  PURE;
    STDMETHOD(Divide)   (  long,  long,  long*  )  PURE;
};

Отдельно можно объвить класс со специальными функциями.

class  IAdvancedMath  :  public  IUnknown
{
public:
    STDMETHOD(Factorial)(  short,  long*  )  PURE;
    STDMETHOD(Fibonacci)(  short,  long*  )  PURE;
};

Вот теперь унаследуем эти классы в новый класс и реализуем методы от наследуемых классов.

class  Math  : 
 public  IMath, 
 public  IAdvancedMath
{
........
};

Кроме этого нам необходим класс фабрики классов IClassFactory, объявить его можно примерно так.

class  MathClassFactory  :  public  IClassFactory
{
protected:
    long        m_lRef;
public:    
	MathClassFactory();    
	~MathClassFactory();
    //  IUnknown   
	STDMETHOD(  QueryInterface(REFIID,  void**  ));
	STDMETHOD_(ULONG,  AddRef());    
	STDMETHOD_(ULONG,  Release());
    //  IClassFactory    
	STDMETHOD(CreateInstance)(LPUNKNOWN,  REFIID,  void**);
	STDMETHOD(LockServer)(BOOL);
};

Как видите, что здесь даже нет упоминания о классах объявленных ранее. Но это упоминание есть в методе CreateInstance

STDMETHODIMP  MathClassFactory::CreateInstance
      (  LPUNKNOWN  pUnkOuter,  REFIID  riid,  void**  ppvObj  )

{

    Math*       pMath;
    HRESULT     hr;
    *ppvObj  =  0;
    pMath  =  new  Math;

    ..............
}

Лично я, например, потратил довольно много времени, чтобы осознать, что интерфейс IUnknown наследуется, а IClassFactory как бы в стороне, и в одном из методов просто создает объект класса унаследованного от IUnknown.

Далее при регистрации классов создается объект фабрики классов, который и создает непосредственно наш класс.

STDAPI DllGetClassObject( REFCLSID rclsid, REFIID riid, void** ppv )
{
	MathClassFactory    *pCF;
	.......
	pCF = new MathClassFactory;
	.......
}

Предыдущий Шаг | Следующий Шаг | Оглавление
Автор Каев Артем - 12.04.2000