только один или два промежуточных интерфейса, которые позволят клиентам создать или найти те экземпляры, которые в конечном счете будут выполнять нужную работу. Например, рассмотрим описанный ранее интерфейс IАре . Объявление интерфейса IАре не нарушит законы СОМ для объекта класса:

class GorillaClass : public IApe

{

public:

// class objects are singletons, so don't delete

// объекты класса существуют в единственном экземпляре,

// так что не удаляйте их

IMPLEMENTUNKNOWNNODELETE (GorillaClass)

BEGININTERFACETABLE(GorillaClass)

IMPLEMENTSINTERFACE(IApe)

ENDINTERFACETABLE()

// IApe methods

// методы IApe

STDMETHODIMP EatBanana(void);

STDMETHODIMP SwingFromTree(void);

STDMETHODIMP getWeight(long *plbs);

};

Если для данного класса C++ может существовать лишь один экземпляр (так ведут себя все объекты классов в СОМ), то в любом заданном экземпляре может быть только одна горилла (gorilla). Для некоторых областей одноэлементных множеств достаточно. В случае с гориллами, однако, весьма вероятно, что клиенты могут захотеть создавать приложения, которые будут использовать несколько различных горилл одновременно. Чтобы обеспечить такое использование, объект класса не должен экспортировать интерфейс IApe , а вместо этого должен экспортировать новый интерфейс, который позволит клиентам создавать новых горилл и/или находить известных горилл по их имени. Это потребует от разработчика определить два класса C++: один для реализации объекта класса и другой для реализации действительных экземпляров класса. Для реализации гориллы класс C++, который определяет экземпляры гориллы, будет реализовывать интерфейс IApe:

class Gorilla : public IApe

{

public:

// Instances are heap-based, so delete when done

// копии размещены в куче, поэтому удаляем после выполнения

IMPLEMENTUNKNOWN()

BEGININTERFACETABLE()

IMPLEMENTSINTERFACE(IApe)

ENDINTERFACETABLE()

// IApe methods

// методы IApe

STDMETHODIMP EatBanana(void);

STDMETHODIMP SwingFromTree(void);

STDMETHODIMP getWeight(long *plbs):

};

Второй интерфейс понадобится для определения тех операций, которые будет реализовывать объект класса Gorilla:

[object, uuid(753A8AAC-A7FF-11d0-8C30-0080C73925BA)]

interface IApeClass : IUnknown

{

HRESULT CreateApe([out, retval] IApe **ppApe);

HRESULT GetApe([in] long nApeID, [out, retval] IApe **ppApe);

[propget]

HRESULT AverageWeight([out, retval] long *plbs);

}

Получив это определение интерфейса, объект класса будет реализовывать методы IApeClass или путем создания новых экземпляров С++-класса Gorilla (в случае CreateApe), или преобразованием произвольно выбранного имени объекта (в данном случае типа integer) в отдельный экземпляр (в случае GetApe):

class GorillaClass : public IApeClass

{

public: IMPLEMENTUNKNOWNNODELETE(GorillaClass)

BEGININTERFACETABLE(GorillaClass)

IMPLEMENTSINTERFACE(IApeClass)

ENDINTERFACETABLE()

STDMETHODIMP CreateApe(Ape **ppApe)

{

if ((*ppApe = new Gorilla) == 0) return EOUTOFMEMORY;

(*ppApe)->AddRef();

return SOK;

}

STDMETHODIMP GetApe(long nApeID, IApe **ppApe)

{

// assume that a table of well-known gorillas is

// being maintained somewhere else

// допустим, что таблица для известных горилл

// поддерживается где-нибудь еще

Добавить отзыв
ВСЕ ОТЗЫВЫ О КНИГЕ В ИЗБРАННОЕ

0

Вы можете отметить интересные вам фрагменты текста, которые будут доступны по уникальной ссылке в адресной строке браузера.

Отметить Добавить цитату