Правильная очистка 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, вызываемую для каждого элемента.

Другие вопросы по тегам