Это ошибка самоопределения в ATL :: CComVariant? - PullRequest
2 голосов
/ 01 июля 2010

ATL::CComVariant имеет несколько операторов присваивания . В реализации я вижу, что в операторах присваивания, принимающих LPCOLESTR, IUnknown* или IDispatch*, первым действием является вызов Clear().

.

Если оператор вызывается таким образом, что передается переменная-член того же объекта

 CComVariant variant;
 variant = L"string";
 variant = variant.bstrVal;

(есть менее глупые способы, которые будут иметь тот же эффект) Clear() освободит инкапсулированный объект, и все последующие действия с теперь висящим указателем приведут к неопределенному поведению.

Я прав или я что-то не так понял?

Ответы [ 2 ]

0 голосов
/ 28 октября 2016
 variant = variant.bstrVal;

Поскольку экземпляр CComVariant управляет указателем строки, ожидаемая логика с таким назначением состоит в том, что экземпляр класса дублирует строку и инициализирует внутренние члены (тип и указатель строки).В настоящее время принадлежащие значения / ресурсы удаляются.

В случае, если мы передаем в качестве аргумента принадлежащий указатель, мы заинтересованы в том, чтобы убедиться, что значение будет продублировано до того, как будет выпущено значение члена.Или в том, что метод правильно обнаруживает регистр «тот же указатель» и игнорирует присвоение.Начиная с Visual Studio 2015 Update 3, ATL делает именно это: он обнаруживает то же самое назначение указателя и немедленно возвращает пропущенную часть выделения / выпуска.То есть реализация ATL точна и хорошо справляется с этим.

0 голосов
/ 28 октября 2016

Это ошибка.

К сожалению, в ATL их еще немало - гораздо больше, чем я имел дело в любой другой библиотеке с аналогичным охватом.

...