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

Вместо того, чтобы удалять компоненты напрямую, мы будем сообщать компоненту, что нам нужен интерфейс или что мы закончили с ним работать. Мы точно знаем, когда начинаем использовать интерфейс, и знаем (обычно), когда перестаем его использовать. Однако, как уже ясно, мы можем не знать, что закончили использовать компонент вообще. Поэтому имеет смысл ограничиться сообщением об окончании работы с данным интерфейсом — и пусть компонент сам отслеживает, когда мы перестаем пользоваться всеми интерфейсами.

Именно для реализации этой стратегии и предназначены еще две функции-члена IUnknown — AddRef и Release.

определение интерфейса IUnknown:

interface IUnknown

{

virtual HRESULT __stdcall QueryInterface(const IID& iid, void** ppv) = 0;

virtual ULONG __stdcall AddRef() = 0;

virtual ULONG __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;

HRESULT hr = pIUnknown->QueryInterface(IID_IX, (void**)&pIX);

if (SUCCEEDED(hr))

{

pIX->Fx(); // Использовать интерфейс IX

pIX->Release(); // Завершить работу с IX

}

pIUnknown->Release(); // Завершить работу с Iunknown

В приведенном выше примере мы фактически закончили работать с IUnknown сразу же после вызова

К-во Просмотров: 513
Бесплатно скачать Контрольная работа: Распределенная обработка данных