ATL::CComVariant
有a handful of assignment operators。我在实现中看到的是,在赋值运算符接受LPCOLESTR
,IUnknown*
或IDispatch*
时,第一个操作是调用Clear()
。
如果以这样的方式调用运算符,则传递同一对象的成员变量
CComVariant variant;
variant = L"string";
variant = variant.bstrVal;
(有更少的愚蠢方式会产生相同的效果)Clear()
将释放封装的对象,而现在悬空指针上的所有后续操作都将导致未定义的行为。
我是正确的还是我误解了什么?
答案 0 :(得分:0)
这是一个错误。
不幸的是,ATL仍然有很多这样的方式 - 比我在任何其他具有类似范围的图书馆中所处理的方式更多。答案 1 :(得分:0)
variant = variant.bstrVal;
当CComVariant
实例管理字符串指针时,具有这种赋值的预期逻辑是类实例复制字符串并初始化内部成员(类型和字符串指针)。当前拥有的价值/资源将被处置。
如果我们将拥有的指针作为参数传递,我们有兴趣确保在释放成员值之前重复该值。或者,该方法正确检测“同一指针”情况并忽略该分配。从Visual Studio 2015 Update 3开始,ATL就是这样做的:它检测到相同的指针赋值并立即返回跳过分配/释放部分。也就是说,ATL实现是准确的并且处理得很好。