Сущность технологии СОМ. Библиотека программиста   ::   Бокс Дональд

Страница: 466 из 528

Рассмотрим следующее определение метода на IDL: HRESULT GetPrimes([in] long nMin, [in] long nMax, [out] IEnumLong **ppe);

Разработчик объекта может создать специальный класс, который генерирует по требованию простые числа и реализует интерфейс IEnumLong :

class PrimeGenerator : public IEnumLong {

LONG m_cRef;

// СОМ reference count

// счетчик ссылок СОМ

long m_nCurrentPrime;

// the cursor

// курсор long m_nMin;

// minimum prime value

// минимальное значение простого числа

long m_nMax;

// maximum prime value

// максимальное значение простого числа

public:

PrimeGenerator(long nMin, long nMax, long nCurrentPrime) : m_cRef(0), m_nMin(nMin), m_nMax(nMax),

m_nCurrentPrime(nCurrentPrime) { }

// IUnknown methods

// методы IUnknown

STDMETHODIMP QueryInterface(REFIID riid, void **ppv);

STDHETHODIMP_(ULONG) AddRef(void);

STDMETHODIMP_(ULONG) Release(void);

// IEnumLong methods

// методы IEnumLong

STDMETHODIMP Next(ULONG, long *, ULONG *);

STDMETHODIMP Skip(ULONG);

STDMETHODIMP Reset(void);

STDMETHODIMP Clone(IEnumLong **ppe);

};

Реализация генератора Next будет просто порождать запрошенное количество простых чисел:

STDMETHODIMP PrimeGenerator::Next(ULONG cElems, long *prgElems, ULONG *pcFetched) {

// ensure that pcFetched is valid if cElems > 1

// удостоверяемся, что pcFetched легален, если cElems больше единицы

if (cElems > 1 && pcFetched == 0) return E_INVALIDARG;

// fill the buffer

// заполняем буфер

ULONG cFetched = 0;

while (cFetched < cElems && m_nCurrentPrime <= m_nMax) {

prgElems[cFetched] = GetNextPrime(m_nCurrentPrime);

m_nCurrentPrime = prgElems[cFetchcd++];

} if (pcFetched)

// some callers may pass NULL

// некоторые вызывающие программы могут передавать NULL

*pcFetched = cFetched;

return cFetched == cElems ? S_OK : S_FALSE;

}

Отметим, что даже если имеются миллионы допустимых значений, одновременно в памяти будет находиться лишь малое их число.

Методу генератора Skip нужно просто генерировать и отбрасывать запрошенное количество элементов:

STDMETHODIMP PrimeGenerator::Skip(ULONG cElems) {

ULONG cEaten = 0; while (cEaten < cElems && m_nCurrentPrime <= m_nMax) {

m_nCurrentPrime = GetNextPrime(m_nCurrentPrime);

cEaten++; }

return cEaten == cElems ? S_OK : S_FALSE;

}

Метод Reset устанавливает курсор на начальное значение:

STDMETHODIMP PrimeGenerator::Reset(void) {

m_nCurrentPrime = m_nMin;

return S_OK;

}

а метод Clone создает новый генератор простых чисел на основе минимума, максимума и текущих значений, выданных существующим генератором:

STDMETHODIMP PrimeGenerator::Clone(IEnumLong **ppe) {

assert(ppe);

*рре = new PrimeGenerator(m_nMin, m_nMax, m_nCurrent);

if (*ppe) (*ppe)->AddRef();

return S_OK;

}

При наличии реализации PrimeGenerator реализация метода GetPrimes текущим объектом становится тривиальной:

STDMETHODIMP MyClass::GetPrimes(long nМin, long nMax, IEnumLong **ppe) {

assert(ppe);

*ppe = new PrimeGenerator (nMin, nMax, nMin);

if (*ppe) (*ppe)->AddRef();

return S_OK;

}
<

|< Пред. 464 465 466 467 468 След. >|

Java книги

Контакты: [email protected]