Изучая вводный пример по Direct2D, наткнулся на интересную конструкцию
- Код: Выделить всё
template<class Interface>
inline void SafeRelease(
Interface **ppInterfaceToRelease
)
{
if (*ppInterfaceToRelease != NULL)
{
(*ppInterfaceToRelease)->Release();
(*ppInterfaceToRelease) = NULL;
}
}
и её последующее применение
- Код: Выделить всё
SafeRelease(&m_pRenderTarget);
SafeRelease(&m_pLightSlateGrayBrush);
SafeRelease(&m_pCornflowerBlueBrush);
Данный код призван свести рутину по освобождению COM объектов до одной строчки.
Ничего удивительного: их дело предложить, моё - сделать по своему
- Код: Выделить всё
if(m_pRenderTarget)
m_pRenderTarget -> Release ();
if(m_pLightSlateGrayBrush)
m_pLightSlateGrayBrush -> Release ();
if(m_pLinearGradientBrush)
m_pLinearGradientBrush -> Release ();
m_pRenderTarget = NULL;
m_pLightSlateGrayBrush = NULL;
m_pLinearGradientBrush = NULL;
Однако попался ещё один пример: распечатка кода BGMusic.cpp
Это пример-исходник с одной из предыдущих версий DirectX (кажется 8й версии, в документе копирайт МикроСофт от 2000 года), в нём предлагался макро подстановочный вариант.
- Код: Выделить всё
#define SAFE_RELEASE(p) { if(p) { (p)->Release(); (p)=NULL;} }
Казалось бы, новый вариант предложил бы компактность (имеется ввиду бинарная, то есть та которая будет сказываться на конечный размер файла. В исходнике в обоих случая будет одна строчка кода), если б не просьба про inline, которая компактность заменяет быстродействием, так как функция будет вставлена во все места, где её будет вызывать.
По ключевому слову template и так получается генерация функции для каждого нового типа, так если б не inline хоть компактность единого существования функции для переменных одного типа.
И в чём собственно преимущество нового подхода в туториале?
p.s.
Если копнуть по литературе, скажем к версии 3й DirectX, то там выступают против макро варианта, ратуют за вариант который выбрал я.
Обычно после вызова Release я присваиваю указателю значение NULL, чтобы облегчить поиск программных ошибок — например, попыток использования недопустимого указателя на интерфейс. Если вы любите макросы (лично я их не люблю), то всегда можете создать макрос RELEASE, который вызывает функцию Release и присваивает указателю значение NULL:
#define RELEASE(p) ((р)->Release(); (p) = NULL;)
Найджел Томпсон - Программирование трехмерной графики для Windows 95