`wil::com_ptr` 是否会重载运算符 &,又名 "address of"?
Does `wil::com_ptr` overload operator &, aka "address of"?
我找到了这段代码 here。
wil::com_ptr<IStream> stream;
CHECK_FAILURE(SHCreateStreamOnFileEx(
L"assets/EdgeWebView2-80.jpg", STGM_READ, FILE_ATTRIBUTE_NORMAL,
FALSE, nullptr, &stream));
根据 SHCreateStreamOnFileEx
的 the manual,最后一个参数的类型应该是 IStream **
。但是,代码片段将 wil::com_ptr<IStream> *
而不是 IStream **
传递给函数。我想知道它是如何工作的。 wil::com_ptr<IStream>
是否重载运算符 &
(又名“地址”)?
对了,我找不到wil::com_ptr
的联机手册。和winrt::com_ptr struct template (C++/WinRT)一样吗?谢谢。
Windows Implementation Libraries (WIL) has its documentation published through its repository's wiki. The wil::com_ptr_t
class template1 is described on the WinRT and COM wrappers 页面。
Object management methods 部分列出了三个 class 成员,它们允许客户端获取存储的接口指针的地址:
T** addressof()
Returns the address of the internal pointer without releasing the current COM object. Do not use this for _Out_
parameters2 because it will leak the current COM object. For _Out_
parameters, use the &
operator, which releases the current COM object before returning the address.
T** put()
Releases the current COM object and returns the address of the internal pointer. Use this method when passing the com_ptr_t
as a _Out_
parameter.
T** operator&()
Same as put()
.
所以回答字面的问题:是的,wil::com_ptr_t
does overload operator&()
到 return 做一些内务处理后的内部接口指针的地址。
wil::com_ptr_t
与 winrt::com_ptr
class template3, part of the C++/WinRT library. Neither of them are related to ATL's CComPtr
or Visual Studio's _com_ptr_t
无关。这是四个官方实现,虽然它们都有相同的目标,即自动化 COM 对象的生命周期管理,但它们在实现上略有不同,结果令人惊讶4.
区别在于以下几个方面:
带有接口指针参数的构造函数
实现可以选择是承担传入接口指针的所有权,还是模型共享所有权让调用者负责 Release()
-ing 传入接口指针。
接受接口指针的赋值运算符
与上面关于传入指针的内容相同,增加了必须处理实例已经持有接口指针的情况。实现可以:
- 静默删除当前持有的接口指针(这是一个错误并不意味着你不会看到它)
- 在分配传入接口指针之前静默
Release()
当前接口
- 如果实例持有接口指针,则抛出异常
正在检索原始接口指针的地址
类似于上面的赋值,智能指针实例已经持有接口的情况需要这样或那样处理:
- 静默删除存储的接口(例如
addressof()
)
- 静默
Release()
当前界面(例如put()
)
- 如果存储的指针不是
nullptr
,则抛出异常
如果您决定使用 COM 智能指针实现,请确保您牢牢掌握其语义。根据所使用的库,相同的 C++ 代码块可能会有不同的行为。
1 wil::com_ptr
是 wil::com_ptr_t
的 alias template,err_policy
模板参数设置为err_exception_policy
.
2 即使 ppstm
被标记为 [=12=,问题中的代码片段也可以安全地通过 stream.addressof()
] 范围。我猜作者使用 operator&()
来代替一致性、可读性和可维护性。
3 虽然 WIL 和 C++/WinRT 是独立的库,但它们可以令人惊讶地互操作 little effort.
4 We're using a smart pointer, so we can't possibly be the source of the leak
我找到了这段代码 here。
wil::com_ptr<IStream> stream;
CHECK_FAILURE(SHCreateStreamOnFileEx(
L"assets/EdgeWebView2-80.jpg", STGM_READ, FILE_ATTRIBUTE_NORMAL,
FALSE, nullptr, &stream));
根据 SHCreateStreamOnFileEx
的 the manual,最后一个参数的类型应该是 IStream **
。但是,代码片段将 wil::com_ptr<IStream> *
而不是 IStream **
传递给函数。我想知道它是如何工作的。 wil::com_ptr<IStream>
是否重载运算符 &
(又名“地址”)?
对了,我找不到wil::com_ptr
的联机手册。和winrt::com_ptr struct template (C++/WinRT)一样吗?谢谢。
Windows Implementation Libraries (WIL) has its documentation published through its repository's wiki. The wil::com_ptr_t
class template1 is described on the WinRT and COM wrappers 页面。
Object management methods 部分列出了三个 class 成员,它们允许客户端获取存储的接口指针的地址:
T** addressof()
Returns the address of the internal pointer without releasing the current COM object. Do not use this for_Out_
parameters2 because it will leak the current COM object. For_Out_
parameters, use the&
operator, which releases the current COM object before returning the address.T** put()
Releases the current COM object and returns the address of the internal pointer. Use this method when passing thecom_ptr_t
as a_Out_
parameter.T** operator&()
Same asput()
.
所以回答字面的问题:是的,wil::com_ptr_t
does overload operator&()
到 return 做一些内务处理后的内部接口指针的地址。
wil::com_ptr_t
与 winrt::com_ptr
class template3, part of the C++/WinRT library. Neither of them are related to ATL's CComPtr
or Visual Studio's _com_ptr_t
无关。这是四个官方实现,虽然它们都有相同的目标,即自动化 COM 对象的生命周期管理,但它们在实现上略有不同,结果令人惊讶4.
区别在于以下几个方面:
带有接口指针参数的构造函数
实现可以选择是承担传入接口指针的所有权,还是模型共享所有权让调用者负责
Release()
-ing 传入接口指针。接受接口指针的赋值运算符
与上面关于传入指针的内容相同,增加了必须处理实例已经持有接口指针的情况。实现可以:
- 静默删除当前持有的接口指针(这是一个错误并不意味着你不会看到它)
- 在分配传入接口指针之前静默
Release()
当前接口 - 如果实例持有接口指针,则抛出异常
正在检索原始接口指针的地址
类似于上面的赋值,智能指针实例已经持有接口的情况需要这样或那样处理:
- 静默删除存储的接口(例如
addressof()
) - 静默
Release()
当前界面(例如put()
) - 如果存储的指针不是
nullptr
,则抛出异常
- 静默删除存储的接口(例如
如果您决定使用 COM 智能指针实现,请确保您牢牢掌握其语义。根据所使用的库,相同的 C++ 代码块可能会有不同的行为。
1 wil::com_ptr
是 wil::com_ptr_t
的 alias template,err_policy
模板参数设置为err_exception_policy
.
2 即使 ppstm
被标记为 [=12=,问题中的代码片段也可以安全地通过 stream.addressof()
] 范围。我猜作者使用 operator&()
来代替一致性、可读性和可维护性。
3 虽然 WIL 和 C++/WinRT 是独立的库,但它们可以令人惊讶地互操作 little effort.
4 We're using a smart pointer, so we can't possibly be the source of the leak