Реферат по предмету "Информатика, программирование"


Распределенная обработка данных

Содержание
 
Задание №1 Реализация интерфейса COM
Задание№1А QueryInterface
Задание№1B Подсчет ссылок
/>/>/>/>Задание №1/>/> Реализацияинтерфейса COM
Цель работы:
Разработатькод на С++, реализующий простой интерфейс СОМ без динамической компоновки:
-      клиенти компонент взаимодействуют через два интерфейса IX иIY, интерфейсы COMреализованы как чисто абстрактные базовые классы С++;
-      вкачестве клиента использовать процедуру main;
-      компонентреализуется классом СА, который наследует как IX так и IY;
-      классСА реализует функции-члены обоих интерфейсов (множественное наследование);
-      клиентсоздает экземпляр компонента (для управления существованием компонента клиентприменяет оператора new и delete), далее он получает указатели на интерфейсы, поддерживаемыекомпонентом, использовать эти указатели анологично указателям на классы С++;
-      выводитьпромежуточные сообщения при использовании интерфейсов IX и IY;
-      удалитькомпонент;
-      вместоопределения интерфейса как класса использовать определение из заголовочногофайла OBJBASE.H
#define interface struct
ифункции-члены объявлять с помощью
virtual void _stdcall … .
Теоретическиесведения:
В СОМ интерфейсы — это все. Для клиента компонент представляетсобой набор интерфейсов. Клиент может взаимодействовать с компонентом СОМтолько через интерфейс. С точки зрения программиста СОМ, интерфейсы — важнаячасть любого приложения. Компоненты сами по себе есть просто детали реализацииинтерфейсов.
Утверждение, что компонент — всего лишь деталь реализацииинтерфейса, конечно, преувеличение. В конце концов, интерфейс без реализацииничего не сделает. Однако компонент можно удалить и заменить другим; если новыйкомпонент поддерживает те же интерфейсы, что и старый, приложение будетработать по-прежнему. Отдельные компоненты сами по себе не определяютприложения. Приложение определяют интерфейсы между компонентами. Покаинтерфейсы неизменны, компоненты могут появляться и исчезать
Теперь рассмотрим код, реализующий простой интерфейс. Вприведенном ниже тексте программы компонент CA использует IX и IY для реализации двухинтерфейсов.
class IX // Первый интерфейс
{
public:
virtualvoid Fx1() = 0;
virtualvoid Fx2() = 0;
};
classIY // Второй интерфейс
{
public:
virtualvoid Fy1() = 0;
virtualvoid Fy2() = 0;
};
classCA: public IX, public IY // Компонент
{
public:
// Реализацияабстрактного базового класса IX
virtualvoid Fx1() { cout
virtualvoid Fx2() { cout
//Реализация абстрактного базового класса IY
virtualvoid Fy1() { cout
virtualvoid Fy2() { cout
};
IX и IY — это чисто абстрактные базовые классы, которые используются дляреализации интерфейсов. Чистоабстрактный базовый класс (pure abstract base class) — это базовый класс,который содержит только чисто виртуальные функции (pure virtual functions). Чисто виртуальнаяфункция — это виртуальная функция, «помеченная =0 — знаком спецификаторачистоты (pure specifier). Чисто виртуальные функции не реализуютсяв классах, в которыхобъявлены. Как видно из приведенного выше примера, функции IX::Fx1, IX::Fx2, IY::Fy1 и IY::Fy2 только декларируются.Реализуются же они в производном классе. В приведенном фрагменте кода компонентCA наследует два чистоабстрактных базовых класса — IX и IY — и реализует их чисто виртуальные функции.
Для того, чтобы реализовать функции-члены IX и IY, CA использует множественноенаследование. Последнее означает, что класс является производным более чем отодного базового класса. Класс С++ чаще всего использует единичное наследование,т.е. имеет только один базовый класс.
 
Текст программы:
 
#include «stdafx.h»
#include«iostream.h»
#include«objbase.h» // Определитьинтерфейс
#include«conio.h»
voidtrace(const char* pMsg) { cout
// Абстрактныеинтерфейсы
interface IX
{
virtual void__stdcall Fx1() = 0;
virtual void__stdcall Fx2() = 0;
};
interface IY
{
virtual void__stdcall Fy1() = 0;
virtual void__stdcall Fy2() = 0;
};
// Реализация интерфейса
class CA: public IX,
public IY
{
public:
// Реализация интерфейса IX
virtual void__stdcall Fx1() { cout
virtual void__stdcall Fx2() { cout
// Реализацияинтерфейса IY
virtual void__stdcall Fy1() { cout
virtual void__stdcall Fy2() { cout
};
// Клиент
int main()
{
trace(«Client:Sozdanie ekzemplyra komponenta»);
CA* pA = new CA;
// Получить указатель IX
IX* pIX = pA;
trace(«Client:Ispol'zovanie interface IX»);
pIX->Fx1();
pIX->Fx2();
// Получить указатель IY
IY* pIY = pA;
trace(«Client:Ispol'zovanie interface IY»);
pIY->Fy1();
pIY->Fy2();
trace(«Client:Delete komponent»);
delete pA;
getch();
return 0; }
Результат работыпрограммы:
 
/>
Вывод:
В данномзадании мы реализововали простой интерфейс СОМ без динамической компоновки. ИнтерфейсыCOM реализованы как чисто абстрактные базовые классы С++, в качестве клиентаиспользовали процедуру main./>/>Задание2 №1А QueryInterface
Цельработы:
1.        Объявитьинтерфейсы IX, IY, IZ. Объявить интерфейс IUnknown.
2.        Реализациякомпонента. Класс СА реализует компонент, поддерживающий интерфейсы IX и IY. Реализовать QueryInterface описанным выше способом.Функцию CreateInstance определить после класса CA. Клиент использует ее,чтобы создать компонент, представляемый при помощи СА, и получить указатель на IUnknown этого компонента. После CreateInstance определить IID для интерфейсов. (Длятого, чтобы определить IID для IUnknown компоновать с UUID.LIB).
3.        Реализацияклиента, роль которого выполняет main. Клиент начинает с создания компонента припомощи CreateInstance. CreateInstance возвращает указатель на интерфейс IUnknown компонента. Клиент припомощи QueryInterface запрашивает через интерфейс IUnknown указатель на интерфейс IX компонента. Анологичнозапросить и IY. Использовать эти указатели для доступа к функциям-членам.Запросить интерфейс IZ. QueryInterface возвращает код ошибки, так как СА не реализует IZ. Далее Клиентзапрашивает указатель на интерфейс IY через указатель на интерфейс IX, pIX. Поскольку компонентподдерживает IY, этот запрос будет успешным, и клиент сможет использоватьвозвращенный указатель на интерфейс IY так же, как он использовал первый указатель.Затем клиент запрашивает интерфейс IUnknown через указатель на IY. Поскольку всеинтерфейсы COM наследуют IUnknown, этот запрос должен быть успешным, причемвозвращенный указатель совпадет с первым указателем, так как. QueryInterface возвращает один и тот жеуказатель на все запросы к IUnknown.
Теоретические сведения:
В COM клиент взаимодействует скомпонентом с помощью интерфейса
IUnknown, который определен взаголовочном файле UNKWN.H:
InterfaceIUnknown
{
virtualHREZULT --stdcall QueryInterface( const IID&iid,
void* * ppv) = 0 ;
virtualULONG --stdcall Addref( ) = 0 ;
virtual ULONG --stdcallRelease( ) = 0 ;
};
Функцию сименем QueryInterface клиент вызывает, чтобы определить, поддерживает ли компонентнекоторый интерфейс. У функции QueryInterface два параметра. Первыйпараметр – идентификатор интерфейса. Второй параметр — адрес, по которому QueryInterface помещает указатель наискомый интерфейс.
QueryInterface возвращает HREZULT – 32-разрядный кодрезультата.
QueryInterface может возвратить либо S_OK, либо E_NOINTERFACE. Клиент не должен прямосравнивать возвращаемое QueryInterface значение с этими константами; для проверки надоиспользовать макросы SUCCEEDED или FAILED.
Получение указателя на IUnknown
Для полученияуказателя на IUnknown использовать функцию, например, CreateInstance которая создаеткомпонент и возвращает указатель на IUnknown:
IUnknown *CreateInstance( )
Реализацияфункции CreateInstance:
IUnknown * pI= static_cast(new CA) ;
PI->Addref() ;
Return pI ;
Использование QueryInterface.
Предположим,что у нас есть указатель на IUnknown, pI. Чтобы определить, можно ли использоватьнекоторый другой интерфейс, мы вызываем QueryInterface, передавая ейидентификатор нужного нам интерфейса. Если QueryInterface отработала успешно, мыможем пользоваться указателем:
void foo(IUnknown* pI)
{
// Определить указательна интерфейс
IX* pIX=NULL;
// Запросить интерфейс IX
HREZULT hr = pI-> QueryInterface(IID_IX, (void**)&pIX) ;
// Проверить значениерезультата
if (SUCCEEDED(hr))
{
// Использовать интерфейс
pIXFx( ) ;
}
}
Реализация QueryInterface.
Запишем QueryInterface для следующегокомпонента, реализуемого классом CA:
Interface IX:IUnknown { /*…*/ } ;
Interface IY:IUnknown { /*…*/ } ;
Class CA: publicIX, public IY { /*…*/ } ;
Следующий фрагмент кодареализует QueryInterface для класса, приведенного выше фрагмента кода.
HREZULT --stdcallCA:: QueryInterface( const IID&iid, void * * ppv);
{
if (iid==IID_IUnknown)
{
// Клиентзапрашивает интерфейс IUnknown
*ppv =static_cast(this) ;
}
else if (iid==IID_IX)
{
// Клиент запрашиваетинтерфейс IX
*ppv = static_cast(this) ;
}
else if (iid==IID_IY)
{
// Клиентзапрашивает интерфейс IY
*ppv =static_cast(this) ;
}
else
{
// Мы не поддерживаемзапрашиваемый клиентом интерфейс.
// Установить возвращаемыйуказатель в NULL.
*ppv = NULL ;
returnE_NOINTERFACE ;
}
static_cast(*ppv)->AddRef( ) ;
return S_OK ;
}
 
Текст программы:
#include«stdafx.h»
#include«iostream.h»
#include«objbase.h»
#include«conio.h»
voidtrace(const char* msg) { cout
// Интерфейсы
interface IX:IUnknown
{
virtual void__stdcall Fx() = 0;
};
interface IY:IUnknown
{
virtual void__stdcall Fy() = 0;
};
interface IZ:IUnknown
{
virtual void__stdcall Fz() = 0;
};
// Предварительныеобъявления GUID
extern const IID IID_IX;
extern constIID IID_IY;
extern constIID IID_IZ;
//
// Компонент
class CA:public IX, public IY
{
// РеализацияIUnknown
virtualHRESULT __stdcall QueryInterface(const IID& iid, void** ppv);
virtual ULONG__stdcall AddRef() { return 0; }
virtual ULONG__stdcall Release() { return 0; }
// РеализацияинтерфейсаIX
virtual void__stdcall Fx() { cout
// РеализацияинтерфейсаIY
virtual void__stdcall Fy() { cout
};
HRESULT__stdcall CA::QueryInterface(const IID& iid, void** ppv)
{
if (iid ==IID_IUnknown)
{
trace(«QueryInterface:Vernyt' ykazatel' na IUnknown»);
*ppv =static_cast(this);
}
else if (iid== IID_IX)
{
trace(«QueryInterface:Vernyt' ykazatel' na IX»);
*ppv =static_cast(this);
}
else if (iid== IID_IY)
{
trace(«QueryInterface:Vernyt' ykazatel' na IY»);
*ppv =static_cast(this);
}
else
{
trace(«QueryInterface:Interface No!»);
*ppv = NULL;
returnE_NOINTERFACE;
}
reinterpret_cast(*ppv)->AddRef();
return S_OK;
}
// Функциясоздания
IUnknown*CreateInstance()
{
IUnknown* pI =static_cast(new CA);
pI->AddRef();
return pI;
}
// IID
//{32bb8320-b41b-11cf-a6bb-0080c7b2d682}
static constIID IID_IX =
{0x32bb8320,0xb41b, 0x11cf,
{0xa6, 0xbb,0x0, 0x80, 0xc7, 0xb2, 0xd6, 0x82}};
//{32bb8321-b41b-11cf-a6bb-0080c7b2d682}
static constIID IID_IY =
{0x32bb8321,0xb41b, 0x11cf,
{0xa6, 0xbb,0x0, 0x80, 0xc7, 0xb2, 0xd6, 0x82}};
//{32bb8322-b41b-11cf-a6bb-0080c7b2d682}
static constIID IID_IZ =
{0x32bb8322,0xb41b, 0x11cf,
{0xa6, 0xbb,0x0, 0x80, 0xc7, 0xb2, 0xd6, 0x82}};
// Клиент
int main()
{
HRESULT hr;
trace(«Client:Polychit' ykazatel' na IUnknown»);
IUnknown*pIUnknown = CreateInstance();
trace(«Client:Polychit' ykazatel' na IX»);
IX* pIX =NULL;
hr =pIUnknown->QueryInterface(IID_IX, (void**)&pIX);
if(SUCCEEDED(hr))
{
trace(«Client:IX polychen»);
pIX->Fx(); //Использовать интерфейс IX
}
trace(«Client:Polychit' ykazatel na IY»);
IY* pIY =NULL;
hr =pIUnknown->QueryInterface(IID_IY, (void**)&pIY);
if(SUCCEEDED(hr))
{
trace(«Client:IY polychen»);
pIY->Fy(); //Использовать интерфейс IY
}
trace(«Client:Zaprosit' nepodderjivaemuy interface»);
IZ* pIZ =NULL;
hr =pIUnknown->QueryInterface(IID_IZ, (void**)&pIZ);
if(SUCCEEDED(hr))
{
trace(«Client:Interface IZ polychen»);
pIZ->Fz();
}
else
{
trace(«Client:No Interface IZ»);
}
trace(«Client:Polychit' Interface IY cherez Interface IX»);
IY* pIYfromIX= NULL;
hr =pIX->QueryInterface(IID_IY, (void**)&pIYfromIX);
if(SUCCEEDED(hr))
{
trace(«Client:IY polychen»);
pIYfromIX->Fy();
}
trace(«Client:Polechit' Interface IUnknown cherez IY»);
IUnknown*pIUnknownFromIY = NULL;
hr =pIY->QueryInterface(IID_IUnknown, (void**)&pIUnknownFromIY);
if(SUCCEEDED(hr))
{
cout
if(pIUnknownFromIY == pIUnknown)
{
cout
}
else
{
cout
}
}
// Удалитькомпонент
deletepIUnknown;
getch();
return 0;
}
 
Результат работыпрограммы:
/>

Вывод:
 
В данномзадании объявили интерфейсы IX, IY, IZ, и интерфейс IUnknown.
Реализоваликомпонент. Класс СА который реализует компонент, поддерживающий интерфейсы IX и IY. Реализовали QueryInterface. Функцию CreateInstance, которая определяется послекласса CA. Клиент использует ее, чтобы создать компонент, представляемыйпри помощи СА, и получили указатель на IUnknown этого компонента./>/>Задание№1B Подсчетссылок
 
Цельработы:
Добавить кпредыдущей программе из лабороторной работы №1А подсчет ссылок. Для этого ккомпоненту добавить реализации двух методов IUnknown – AddRef и Release.используя функции Win32 InterlockedIncrement и InterlockedDecrement. Функцию AddRef вызывают CreateInstance и QueryInterface для соответствующихуказателей на интерфейсы. Вызовы Release добавить в клиенте, чтобы обозначить окончаниеработы с различными интерфейсами.
Ликвидироватькомпонент с помощью деструктора.
Теоретические сведения:
Вместо того, чтобы удалять компоненты напрямую, мы будем сообщатькомпоненту, что нам нужен интерфейс или что мы закончили с ним работать. Мыточно знаем, когда начинаем использовать интерфейс, и знаем (обычно), когда перестаемего использовать. Однако, как уже ясно, мы можем не знать, что закончилииспользовать компонент вообще. Поэтому имеет смысл ограничиться сообщением обокончании работы с данным интерфейсом — и пусть компонент сам отслеживает,когда мы перестаем пользоваться всеми интерфейсами.
Именно для реализации этой стратегии и предназначены еще двефункции-члена IUnknown — AddRef и Release.
определение интерфейса IUnknown:
interface IUnknown
{
virtual HRESULT __stdcall QueryInterface(const IID& iid,void** ppv) = 0;
virtual ULONG __stdcall AddRef() = 0;
virtualULONG __stdcall Release() = 0;
};
AddRef и Release реализуют и техникууправления памятью, известную как подсчет ссылок (reference counting).
Подсчет ссылок — простой и быстрый способ, позволяющий компонентамсамим удалять себя. Компонент СОМ поддерживает счетчик ссылок. Когда клиентполучает некоторый интерфейс, значение этого счетчика увеличивается на единицу.Когда клиент заканчивает работу с интерфейсом, значение на единицу уменьшается.Когда оно доходит до нуля, компонент удаляет себя из памяти. Клиент такжеувеличивает счетчик ссылок, когда создает новую ссылку на уже имеющийся у негоинтерфейс. Как Вы, вероятно, догадались, увеличивается счетчик вызовом AddRef, а уменьшается — вызовомRelease.
Для того, чтобы пользоваться подсчетом ссылок, необходимо знатьлишь три простых правила:
1. Вызывайте AddRefперед возвратом. Функции, возвращающиеинтерфейсы, перед возвратом всегда
должны вызывать AddRef для соответствующего указателя. Это такжеотносится к QueryInterface и функции CreateInstance. Таким образом, Вам не нужно вызывать AddRef в своей программе после получения(от функции) указателя на интерфейс.
2. По завершении работы вызывайте Release. Когда Вы закончили работус интерфейсом, следует вызвать для него Release.
3. Вызывайте AddRefпосле присваивания. Когда бы Вы ниприсваивали один указатель на интерфейс другому, вызывайте AddRef. Иными словами: следуетувеличить счетчик ссылок каждый раз, когда создается новая ссылка на данныйинтерфейс.
Приведенныйниже фрагмент кода создает компонент и получает указатель на интерфейс IX. Мы не вызываем AddRef, так как за нас этоделают CreateInstance и QueryInterface. Однако мы вызываем Release как для интерфейса IUnknown, возвращенного CreateInstance, так и для интерфейса IX, возвращенного QueryInterface.
//Создать компонент
IUnknown*pIUnknown = CreateInstance();
// Получитьинтерфейс IX
IX* pIX = NULL;
HRESULThr = pIUnknown->QueryInterface(IID_IX, (void**)&pIX);
if(SUCCEEDED(hr))
{
pIX->Fx();// Использовать интерфейс IX
pIX->Release(); // Завершить работу сIX
}
pIUnknown->Release(); // Завершить работу сIunknown
В приведенном выше примере мы фактически закончили работать с IUnknown сразу же после вызова
QueryInterface, так что его можноосвободить раньше.
//Создать компонент
IUnknown*pIUnknown = CreateInstance();
// Получитьинтерфейс IX
IX* pIX = NULL;
HRESULThr = pIUnknown->QueryInterface(IID_IX, (void**)&pIX);
// Завершитьработу с IUnknown
pIUnknown->Release();
//Использовать IX, если он был получен успешно
if (SUCCEEDED(hr))
{
pIX->Fx(); // Использоватьинтерфейс IX
pIX->Release(); // Завершить работу сIX
}
Легко забыть, что всякий раз, когда Вы копируете указатель наинтерфейс, надо увеличить его счетчик ссылок. В приведенном далее фрагментекода делается еще одна ссылка на интерфейс IX. В общем случаенеобходимо увеличивать счетчик ссылок всякий раз, когда создается копияуказателя на интерфейс, о чем говорит приведенное выше правило 3.
//Создать компонент
IUnknown*pIUnknown = CreateInstance();
IX*pIX = NULL;
HRESULThr = pIUnknown->QueryInterface(IID_IX, (void**)&pIX);
pIUnknown->Release();
if(SUCCEEDED(hr))
{
pIX->Fx(); // Использоватьинтерфейс IX
IX* pIX2 = pIX; // Создать копию pIX
pIX2->AddRef(); // Увеличить счетчикссылок
pIX2->Fx(); // Что-то делать припомощи pIX2
pIX2->Release(); // Завершить работу сpIX2
pIX->Release(); // Завершить работу сpIX
}
Клиент сообщает компоненту о своем желании использовать интерфейс,когда вызывается
QueryInterface. QueryInterface вызывает AddRef для запрашиваемогоинтерфейса. Когда клиент заканчивает работу с интерфейсом, он вызывает дляэтого интерфейса Release. Компонент остается в памяти, ожидая, пока счетчик ссылок нестанет равен 0. Когда счетчик становится нулем, компонент сам себя удаляет.
 
Текст программы:
 
#include«stdafx.h»
#include«iostream.h»
#include«objbase.h»
#include«conio.h»
voidtrace(const char* msg) { cout
// Предварительныеописания GUID
extern const IID IID_IX;
extern constIID IID_IY;
extern constIID IID_IZ;
// Интерфейсы
interface IX:IUnknown
{
virtual void__stdcall Fx() = 0;
};
interface IY:IUnknown
{
virtual void__stdcall Fy() = 0;
};
interface IZ:IUnknown
{
virtual void__stdcall Fz() = 0;
};
// Компонент
class CA:public IX, public IY
{
// РеализацияIUnknown
virtualHRESULT __stdcall QueryInterface(const IID& iid, void** ppv);
virtual ULONG__stdcall AddRef();
virtual ULONG__stdcall Release();
// Реализацияинтерфейса IX
virtual void__stdcall Fx() { cout
// Реализацияинтерфейса IY
virtual void__stdcall Fy() { cout
public:
// Конструктор
CA(): m_cRef(0) {}
// Деструктор
~CA() {trace(«CA: Likvidirovat' seby»); }
private:
long m_cRef;
};
HRESULT__stdcall CA::QueryInterface(const IID& iid, void** ppv)
{
if (iid ==IID_IUnknown)
{
trace(«CAQI: Vozvratit' ykazateel na IUnknown»);
*ppv =static_cast(this);
}
else if (iid== IID_IX)
{
trace(«CAQI: Vozvratit' ykazateel na IX»);
*ppv =static_cast(this);
}
else if (iid== IID_IY)
{
trace(«CAQI:Vozvratit' ykazateel na IY»);
*ppv =static_cast(this);
}
else
{
trace(«CAQI: Interface No!»);
*ppv = NULL;
returnE_NOINTERFACE;
}
reinterpret_cast(*ppv)->AddRef();
return S_OK;
}
ULONG__stdcall CA::AddRef()
{
cout
returnInterlockedIncrement(&m_cRef);
}
ULONG__stdcall CA::Release()
{
cout
if(InterlockedDecrement(&m_cRef) == 0)
{
delete this;
return 0;
}
return m_cRef;
}
//
// Функциясоздания
//
IUnknown*CreateInstance()
{
IUnknown* pI =static_cast(new CA);
pI->AddRef();
return pI;
}
//
// IID
//
//{32bb8320-b41b-11cf-a6bb-0080c7b2d682}
static constIID IID_IX =
{0x32bb8320,0xb41b, 0x11cf,
{0xa6, 0xbb,0x0, 0x80, 0xc7, 0xb2, 0xd6, 0x82}};
//{32bb8321-b41b-11cf-a6bb-0080c7b2d682}
static constIID IID_IY =
{0x32bb8321,0xb41b, 0x11cf,
{0xa6, 0xbb,0x0, 0x80, 0xc7, 0xb2, 0xd6, 0x82}};
//{32bb8322-b41b-11cf-a6bb-0080c7b2d682}
static constIID IID_IZ =
{0x32bb8322,0xb41b, 0x11cf,
{0xa6, 0xbb,0x0, 0x80, 0xc7, 0xb2, 0xd6, 0x82}};
//
// Клиент
//
int main()
{
HRESULT hr;
trace(«Client:Polychit' ykazatel IUnknown»);
IUnknown*pIUnknown = CreateInstance();
trace(«Client:Polychit' Interface IX»);
IX* pIX =NULL;
hr =pIUnknown->QueryInterface(IID_IX, (void**)&pIX);
if(SUCCEEDED(hr))
{
trace(«Client:IX polychen»);
pIX->Fx(); // Использоватьинтерфейс IX
pIX->Release();
}
trace(«Client:Polychit' Interface IY»);
IY* pIY =NULL;
hr =pIUnknown->QueryInterface(IID_IY, (void**)&pIY);
if(SUCCEEDED(hr))
{
trace(«Client:IY polychen»);
pIY->Fy(); // Использоватьинтерфейс IY
pIY->Release();
}
trace(«Client:Zaprosit' nepodderjivaemue Interface»);
IZ* pIZ =NULL;
hr =pIUnknown->QueryInterface(IID_IZ, (void**)&pIZ);
if(SUCCEEDED(hr))
{
trace(«Client:Interface IZ polychen»);
pIZ->Fz();
pIZ->Release();
}
else
{
trace(«Client:No! Interface IZ»);
}
trace(«Client:Osvobodit' Interface IUnknown»);
pIUnknown->Release();
getch();
return 0;
}
 

Результат работыпрограммы:
 
/>
Вывод:
В этомзадании мы добавили подсчет ссылок. Для этого к компоненту добавили реализациюдвух методов IUnknown – AddRef и Release, используя функции Win32 InterlockedIncrement и InterlockedDecrement. Функцию AddRef вызывают CreateInstance и QueryInterface для соответствующихуказателей на интерфейсы. Вызовы Release добавили в клиенте, чтобы обозначить окончаниеработы с различными интерфейсами. Ликвидировали компонент с помощью деструктора.


Не сдавайте скачаную работу преподавателю!
Данный реферат Вы можете использовать для подготовки курсовых проектов.

Поделись с друзьями, за репост + 100 мильонов к студенческой карме :

Пишем реферат самостоятельно:
! Как писать рефераты
Практические рекомендации по написанию студенческих рефератов.
! План реферата Краткий список разделов, отражающий структура и порядок работы над будующим рефератом.
! Введение реферата Вводная часть работы, в которой отражается цель и обозначается список задач.
! Заключение реферата В заключении подводятся итоги, описывается была ли достигнута поставленная цель, каковы результаты.
! Оформление рефератов Методические рекомендации по грамотному оформлению работы по ГОСТ.

Читайте также:
Виды рефератов Какими бывают рефераты по своему назначению и структуре.