Правильная очистка CComSafeArray<VARIANT>
Дано:
{
CComSafeArray<VARIANT> sa;
CComVariant ccv(L"test");
sa.Add(ccv, TRUE);
}
Я надеялся, что dtor из CComSafeArray будет вызывать::VariantClear для каждого содержащегося в нем члена, и документация, кажется, указывает, что:
В некоторых случаях может быть предпочтительнее очистить вариант в коде без вызова VariantClear. Например, вы можете изменить тип варианта VT_I4 на другой тип без вызова этой функции. Safearrays BSTR будет вызывать SysFreeString для каждого элемента, а не VariantClear. Однако вы должны вызвать VariantClear, если VT_type получен, но не может быть обработан. Варианты Safearrays также будут вызывать VariantClear для каждого участника.
(источник: http://msdn.microsoft.com/en-us/library/windows/desktop/ms221165(v=vs.85).aspx)
Но я не вижу такой вещи в коде в atlsafe.h.
Я просто смотрю не в том месте, или это должно произойти как побочный эффект::SafeArrayDestroy() - единственное, что происходит через dtor CComSafeArray.
1 ответ
В конечном счете VariantClear
будет вызвано содержимое объекта CComSafeArray, хотя и после прохождения через несколько слоев. CComSafeArray::~CComSafeArray()
звонки CComSafeArray::Destroy()
который в конечном итоге является оберткой SafeArrayDestroy()
:
HRESULT Destroy()
{
HRESULT hRes = S_OK;
if (m_psa != NULL)
{
hRes = Unlock();
if (SUCCEEDED(hRes))
{
hRes = SafeArrayDestroy(m_psa);
if (SUCCEEDED(hRes))
m_psa = NULL;
}
}
return hRes;
}
SafeArrayDestroy()
задокументировано как вызов VariantClear
на его содержимое, если оно содержит ВАРИАНТЫ:
Безопасные массивы варианта будут иметь функцию VariantClear, вызываемую для каждого члена, а безопасные массивы BSTR будут иметь функцию SysFreeString, вызываемую для каждого элемента.