Да, този код е наред и едва ли може да се направи по-добре, като се има предвид как е проектиран ATL::CComVariant
, освен ако не отделите известно време за писане на помощни функции. Няколко мисли за това.
Предаването на CComVariant
като in VARIANT
е добре - основната част просто се копира по член в параметъра на функцията и се използва от извиканата функция оттам. Не се случва дълбоко копиране и това е добре, извикваният може да използва копието също така, ако иска да копира дълбоко параметъра или AddRef()
него - той все още може да го направи.
Предаването на адрес на CComVariant
като in VARIANT
е добре (CComVariant*
е имплицитно upcast към VARIANT*
, функцията има достъп до подобекта), но не е най-добрият код в света. Ето защо. Има много подобни класове, които притежават ресурси, най-важните от тях са ATL::CComBSTR
, _bstr_t
, ATL::CComPtr
, _com_ptr_t
и всички те са operator&()
претоварени, а също и тези от тях, които принадлежат към ATL
пространството от имена, просто връщат указателя към съхранения указател, но _bstr_t
и _com_ptr_t
освобождаване на притежавания обект преди връщане на указателя. Ето защо това:
ATL::CComPtr<IUnknown> ptr( initialize() );
&ptr;
и този:
_com_ptr_t<IUnknown> ptr( initialize() );
&ptr;
имат различни ефекти. Нито ATL::CComVariant
, нито _variant_t
са operator&()
претоварени, което усложнява нещата още малко. По-чистият начин би бил да се използва метод за "извличане на достъп", като _variant_t::GetVARIANT()
, но ATL::CComVariant
няма такъв метод. Така че използването на &
е единствената опция, която имате тук.
Предаването на CComVariant
адрес, получен с помощта на &
като out VARIANT*
е добре, но отново не е най-добрият код в света. Добре е, когато знаете със сигурност, че вариантът е празен, но този код:
CComVariant var( obtainIUnknown() );
foo( whatever, whatever, &var );
сляпо ще презапише указателя и ще доведе до изтичане на по-рано споменатия обект. По-добър начин би бил да се използва нещо като _variant_t::GetAddress()
, което изчиства варианта и след това връща указател към необработения VARIANT
, но отново ATL::CComVariant
няма такъв метод.
Така че долният код е добре, просто внимавайте, когато го променяте. Ако се случи да пишете много код като този, може да е по-добре да пишете помощни функции, които извършват тези манипулации за "извличане".
person
sharptooth
schedule
18.04.2016
/*[in]*/ VARIANT*
-- наистина ли? - person Roger Lipscombe   schedule 15.04.2016CComVariant
екземпляр, който автоматично освобождава всичко, което е записано в него, когато променливата излезе извън обхвата. Тоест, вие сте този, който освобождава ресурси и го правите с помощта на този помощен клас. - person Roman R.   schedule 17.04.2016