ПРОГРАМИРУЕМ 3D ГРАФИКУ ИСПОЛЬЗУЯ DirectX


Интерфейсы и классы - часть 4


pIFrame-»AddVisual (pIMesh) ;

Если взглянуть на код функции AddVisual в IDirect3DRMFrame, вы увидите что-нибудь в таком роде:

Работа с интерфейсами СОМ-объектов Tflil 63

HRESULT IDirect3DRMFrame::AddVisual(IDirect3DRMVisual * pIVisual)

f

pIVisual-»AddRef () ;

AddVisualToList(pIVisual) ;

}

Функция AddRef, входящая в интерфейс Визуального элемента (визуальный интерфейс), увеличивает счетчик обращений к объекту-сетке. Зачем? Затем, что во время существования объекта-фрейма нельзя допустить уничтожения объекта, предоставляющего ему визуальный интерфейс. После уничтожения фрейма или удаления из него конкретного визуального интерфейса код фрейма освобождает объект-сетку:

pIVisual-»Release () ;

Следовательно, после освобождения объекта-сетки последним фреймом счетчик обращений объекта упадет до нуля, и он самоуничтожится.

Какой же вывод следует сделать из всего этого? Если вы правильно обращаетесь с интерфейсами СОМ-объектов с помощью функций AddRef и Release, вам никогда не придется следить за тем, какие объекты присутствуют в памяти и когда их можно удалять, поскольку внутренний счетчик обращений самостоятельно справится с этой работой.

Позвольте дать пару последних рекомендаций по работе с СОМ-объектами. Любая функция, которая возвращает указатель на интерфейс, перед тем как вернуть управление, вызывает AddRef для увеличения счетчика обращений; после завершения работы с указателем необходимо вызвать Release, чтобы избежать ненужного хранения объектов в памяти. Если вы копируете указатель на интерфейс, вызовите AddRef для копии и освободите оба указателя функцией Release, когда надобность в них отпадет. Помните о том, что возврат указателя на интерфейс одной из ваших функций фактически равносилен его копированию. Перед тем, как возвращать указатель, не забудьте вызвать для него AddRef.

А теперь я собираюсь нарушить только что установленное правило. Если вы стопроцентно уверены в том, что делаете, то при копировании указателя можно обойтись и без вызова AddRef, однако при этом следует неуклонно следить за тем, чтобы функция Release была вызвана нужное количество раз. Лишние вызовы Release приведут к уничтожению используемого объекта, их нехватка — к непроизводительным расходам памяти. Просмотрев исходные тексты библиотеки 3dPlus, вы убедитесь, что во многих объектах C++ присутствует функция Getlnterface. Она возвращает указатель на тот интерфейс, для которого данный класс C++ выступает в роли оболочки. Я сделал это из соображений удобства и производительности. Функция Getlnterface не увеличивает счетчик обращений, так что при вызове какой-либо из функций Getlnterface не следует вызывать Release для возвращаемого указателя.




Начало  Назад  Вперед



Книжный магазин