они часто делают это. В момент написания этой книги классы, которые будут встраиваться в среду Microsoft Transaction Server (MTS),
Интерфейс
Предполагая, что объект класса экспортирует интерфейс
HRESULT CreateAGorillaAndEatBanana()
{
IClassFactory *pcf = 0;
// find the class object находим объект класса
HRESULT hr = CoGetClassObject(CLSI
if (SUCCEEDED(hr))
{
IApe *pApe = 0;
// use the class object to create a gorilla
// используем объект класса для создания gorilla
hr = pcf->CreateInstance(0, II
// we're done with the class object, so release it
// мы закончили с объектом класса, поэтому освобождаем его
pcf->Release();
if (SUCCEEDED(hr))
{
// tell the new gorilla to eat a banana
// приказываем новой горилле есть банан
hr = pApe->EatBanana();
pApe->Release();
}
}
return hr;
}
Этот код является семантически идентичным варианту с функцией, которая использовала интерфейс
Для того чтобы предыдущий пример работал корректно, объекту класса
{
public:
IMPLEMEN
EN
STDMETHODIMP CreateInstance(IUnknown *pUnkOuter, REFIID riid, void **ppv)
{
*ppv = 0;
if (pUnkOuter != 0)
// we don't support aggregation yet
// мы еще не поддерживаем агрегирование
return CLAS
// create a new instance of our C++ class Gorilla
// создаем новый экземпляр нашего С++-класса Gorilla
Gorilla *p = new Gorilla;
if (p == 0) return
// increment reference count by one
// увеличиваем счетчик ссылок на единицу
p->AddRef();
// store the resultant interface pointer into *ppv
// записываем результирующий указатель интерфейса в *ppv
HRESULT hr = p->QueryInterface(riid, ppv);
// decrement reference count by one, which will delete the
// object if QI fails
// уменьшаем на единицу счетчик ссылок,
// что уничтожит объект при отказе QI
p->Release();
// return result of Gorilla::QueryInterface
// возвращаем результат работы Gorilla::QueryInterface
return hr;
}
STDMETHODIMP LockServer(BOOL bLock);
};
Реализация